name: Auto Publish Rust Package

permissions:
  contents: write
  packages: write

on:
  push:
    branches:
      - master

jobs:
  publish:
    runs-on: ubuntu-latest

    steps:
      # Step 1: Checkout repo
      - name: Checkout repository
        uses: actions/checkout@v4

      # Step 2: Setup Rust
      - name: Setup Rust
        uses: actions-rust-lang/setup-rust-toolchain@v1

      # Step 3: Install toml-cli to read Cargo.toml
      - name: Install toml-cli
        run: cargo install toml-cli

      # Step 4: Get crate name and version
      - name: Get crate info
        id: crate
        run: |
          VERSION=$(toml get -r Cargo.toml package.version)
          NAME=$(toml get -r Cargo.toml package.name)
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "name=$NAME" >> $GITHUB_OUTPUT
          echo "Found crate $NAME version $VERSION"

      # Step 5: Check if version exists on crates.io
      - name: Check crates.io
        id: check_crates
        run: |
          VERSION=${{ steps.crate.outputs.version }}
          NAME=${{ steps.crate.outputs.name }}
          # If the version is not found, set publish=true
          if curl -s "https://crates.io/api/v1/crates/$NAME/$VERSION" | grep -q '"errors":'; then
            echo "Version $VERSION not found on crates.io, will publish"
            echo "publish=true" >> $GITHUB_OUTPUT
          else
            echo "Version $VERSION already exists on crates.io, skipping publish"
            echo "publish=false" >> $GITHUB_OUTPUT
          fi

      # Step 6: Extract changelog for this version
      - name: Extract changelog
        if: steps.check_crates.outputs.publish == 'true'
        id: changelog
        run: |
          VERSION=${{ steps.crate.outputs.version }}
          
          # Extract content between this version header and the next version header
          NOTES=$(awk "
            /^## \[${VERSION}\]/ { found=1; next }
            /^## \[/ { if(found) exit }
            found { print }
          " CHANGELOG.md)
          
          # Fallback if no changelog entry found
          if [ -z "$NOTES" ]; then
            NOTES="Released version ${VERSION}"
          fi
          
          # Handle multi-line output for GitHub Actions
          echo "notes<<EOF" >> $GITHUB_OUTPUT
          echo "$NOTES" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      # Step 7: Tag the commit with the version if publishing
      - name: Tag version
        if: steps.check_crates.outputs.publish == 'true'
        run: |
          VERSION=${{ steps.crate.outputs.version }}
          git config user.name "github-actions"
          git config user.email "github-actions@github.com"
          git tag $VERSION
          git push origin $VERSION
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      # Step 8: Publish to crates.io if version is new
      - name: Publish to crates.io
        if: steps.check_crates.outputs.publish == 'true'
        run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      # Step 9: Create GitHub release if version is new
      - name: Create GitHub release
        if: steps.check_crates.outputs.publish == 'true'
        uses: ncipollo/release-action@v1
        with:
          tag: ${{ steps.crate.outputs.version }}
          name: v${{ steps.crate.outputs.version }}
          body: ${{ steps.changelog.outputs.notes }}
          makeLatest: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}