name: Release

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write
  packages: write

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - name: Cache dependencies
        uses: Swatinem/rust-cache@v2

      - name: Check formatting
        run: cargo fmt --all -- --check

      - name: Run clippy
        run: cargo clippy -- -D warnings -A deprecated

      - name: Run tests
        run: cargo test --all-features

  build:
    name: Build and release
    runs-on: ubuntu-latest
    needs: test
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Cache dependencies
        uses: Swatinem/rust-cache@v2

      - name: Install git-cliff
        run: cargo install git-cliff

      - name: Update version and generate changelog
        run: |
          VERSION=${GITHUB_REF_NAME#v}
          echo "Updating version to: $VERSION"

          # Update Cargo.toml version — use POSIX character classes so the
          # pattern matches regardless of how many spaces surround '=' in the
          # version line (e.g. 'version      = "0.1.0"').
          sed -i 's/^version[[:space:]]*=[[:space:]]*"[^"]*"/version      = "'"$VERSION"'"/' Cargo.toml

          # Verify the substitution took effect.
          UPDATED=$(grep '^version[[:space:]]*=' Cargo.toml | head -1 | sed 's/^version[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/')
          if [ "$UPDATED" != "$VERSION" ]; then
            echo "ERROR: Failed to update version in Cargo.toml (got '$UPDATED', expected '$VERSION')"
            exit 1
          fi
          echo "Cargo.toml version updated to $VERSION"

          # Regenerate full changelog
          git-cliff --config cliff.toml --latest --output CHANGELOG.md

          # Determine previous tag for release notes range
          LAST_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")

          if [ -n "$LAST_TAG" ]; then
            git-cliff --config cliff.toml ${LAST_TAG}..${{ github.ref_name }} --strip header > CLIFF_CHANGES.md
          else
            git-cliff --config cliff.toml --tag ${{ github.ref_name }} --strip header > CLIFF_CHANGES.md
          fi

          # Build release notes
          echo "# tui-file-explorer ${VERSION}" > RELEASE_CHANGELOG.md
          echo "" >> RELEASE_CHANGELOG.md
          echo "## What's New" >> RELEASE_CHANGELOG.md
          echo "" >> RELEASE_CHANGELOG.md

          if [ -n "$LAST_TAG" ]; then
            echo "### Changes since ${LAST_TAG}:" >> RELEASE_CHANGELOG.md
          else
            echo "### Initial Release" >> RELEASE_CHANGELOG.md
          fi

          echo "" >> RELEASE_CHANGELOG.md
          cat CLIFF_CHANGES.md >> RELEASE_CHANGELOG.md

          echo "" >> RELEASE_CHANGELOG.md
          echo "## Installation" >> RELEASE_CHANGELOG.md
          echo "" >> RELEASE_CHANGELOG.md
          echo "Add to your \`Cargo.toml\`:" >> RELEASE_CHANGELOG.md
          echo "" >> RELEASE_CHANGELOG.md
          echo "\`\`\`toml" >> RELEASE_CHANGELOG.md
          echo "[dependencies]" >> RELEASE_CHANGELOG.md
          echo "tui-file-explorer = \"${VERSION}\"" >> RELEASE_CHANGELOG.md
          echo "\`\`\`" >> RELEASE_CHANGELOG.md
          echo "" >> RELEASE_CHANGELOG.md
          echo "Or via cargo-add:" >> RELEASE_CHANGELOG.md
          echo "" >> RELEASE_CHANGELOG.md
          echo "\`\`\`bash" >> RELEASE_CHANGELOG.md
          echo "cargo add tui-file-explorer" >> RELEASE_CHANGELOG.md
          echo "\`\`\`" >> RELEASE_CHANGELOG.md
          echo "" >> RELEASE_CHANGELOG.md
          echo "## Quick Start" >> RELEASE_CHANGELOG.md
          echo "" >> RELEASE_CHANGELOG.md
          echo "\`\`\`rust" >> RELEASE_CHANGELOG.md
          echo "use tui_file_explorer::{FileExplorer, ExplorerOutcome, render};" >> RELEASE_CHANGELOG.md
          echo "" >> RELEASE_CHANGELOG.md
          echo "let mut explorer = FileExplorer::new(" >> RELEASE_CHANGELOG.md
          echo "    std::env::current_dir().unwrap()," >> RELEASE_CHANGELOG.md
          echo "    vec![\"iso\".into(), \"img\".into()]," >> RELEASE_CHANGELOG.md
          echo ");" >> RELEASE_CHANGELOG.md
          echo "\`\`\`" >> RELEASE_CHANGELOG.md

          echo "Generated release notes:"
          cat RELEASE_CHANGELOG.md

      - name: Build release
        run: cargo build --release --all-features

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v1
        with:
          body_path: RELEASE_CHANGELOG.md
          files: |
            LICENSE
            README.md
            CHANGELOG.md
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Publish to crates.io
        if: env.CRATES_IO_TOKEN != ''
        env:
          CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
        run: |
          echo "Publishing to crates.io..."
          cargo publish --token $CRATES_IO_TOKEN --allow-dirty

      - name: Skip crates.io publish
        if: env.CRATES_IO_TOKEN == ''
        env:
          CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
        run: |
          echo "CRATES_IO_TOKEN not set — skipping crates.io publication."
          echo "Add CRATES_IO_TOKEN to your GitHub repository secrets to enable auto-publish."
