name: Publish to crates.io

on:
  release:
    types: [created]
  workflow_dispatch:
    inputs:
      dry_run:
        description: 'Dry run (do not actually publish)'
        required: false
        default: 'false'
        type: choice
        options:
          - 'true'
          - 'false'

jobs:
  publish:
    name: Publish to crates.io
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
      
      - name: Cache cargo registry
        uses: actions/cache@v4
        with:
          path: ~/.cargo/registry
          key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
      
      - name: Cache cargo index
        uses: actions/cache@v4
        with:
          path: ~/.cargo/git
          key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
      
      - name: Check version consistency
        run: |
          # Extract version from Cargo.toml
          CARGO_VERSION=$(grep "^version" Cargo.toml | head -1 | cut -d'"' -f2)
          echo "Cargo.toml version: $CARGO_VERSION"
          
          # Extract tag version (remove 'v' prefix if present)
          if [ "${{ github.event_name }}" = "release" ]; then
            TAG_VERSION=$(echo "${{ github.event.release.tag_name }}" | sed 's/^v//')
            echo "Release tag version: $TAG_VERSION"
            
            # Check if versions match
            if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then
              echo "Error: Cargo.toml version ($CARGO_VERSION) does not match tag version ($TAG_VERSION)"
              exit 1
            fi
          fi
      
      - name: Run tests
        run: cargo test
      
      - name: Check if already published
        id: check
        run: |
          CRATE_NAME=$(grep "^name" Cargo.toml | head -1 | cut -d'"' -f2)
          CRATE_VERSION=$(grep "^version" Cargo.toml | head -1 | cut -d'"' -f2)
          
          # Check if this version is already published
          if cargo search $CRATE_NAME | grep -q "^$CRATE_NAME = \"$CRATE_VERSION\""; then
            echo "Version $CRATE_VERSION is already published"
            echo "already_published=true" >> $GITHUB_OUTPUT
          else
            echo "Version $CRATE_VERSION is not yet published"
            echo "already_published=false" >> $GITHUB_OUTPUT
          fi
      
      - name: Publish to crates.io (dry run)
        if: github.event.inputs.dry_run == 'true' || (github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run != 'false')
        run: |
          cargo publish --dry-run
          echo "Dry run completed successfully!"
      
      - name: Publish to crates.io
        if: |
          steps.check.outputs.already_published == 'false' &&
          (github.event_name == 'release' || github.event.inputs.dry_run == 'false')
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: |
          cargo publish --token $CARGO_REGISTRY_TOKEN
          echo "Successfully published to crates.io!"