name: Release

on:
  workflow_dispatch:
    inputs:
      action:
        description: 'Action to perform'
        required: true
        type: choice
        options:
          - bump-patch
          - bump-minor
          - bump-major
          - build-binaries
      version:
        description: 'Version to build (only for build-binaries, e.g., 0.1.1)'
        required: false
        type: string

  pull_request:
    types: [closed]
    branches: [main]

env:
  CARGO_TERM_COLOR: always

jobs:
  create-release-pr:
    name: Create Release PR
    if: github.event_name == 'workflow_dispatch' && startsWith(github.event.inputs.action, 'bump-')
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install git-cliff
        uses: taiki-e/install-action@git-cliff

      - name: Get current version
        id: current
        run: |
          VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Calculate new version
        id: new
        run: |
          IFS='.' read -r major minor patch <<< "${{ steps.current.outputs.version }}"
          case "${{ inputs.action }}" in
            bump-major)
              major=$((major + 1))
              minor=0
              patch=0
              ;;
            bump-minor)
              minor=$((minor + 1))
              patch=0
              ;;
            bump-patch)
              patch=$((patch + 1))
              ;;
          esac
          NEW_VERSION="${major}.${minor}.${patch}"
          echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
          echo "Bumping ${{ steps.current.outputs.version }} -> $NEW_VERSION"

      - name: Update Cargo.toml version
        run: |
          sed -i 's/^version = ".*"/version = "${{ steps.new.outputs.version }}"/' Cargo.toml

      - name: Update Cargo.lock
        run: cargo generate-lockfile

      - name: Generate changelog
        run: git cliff --tag "v${{ steps.new.outputs.version }}" -o CHANGELOG.md

      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v7
        with:
          commit-message: "chore(release): prepare v${{ steps.new.outputs.version }}"
          branch: release/v${{ steps.new.outputs.version }}
          title: "release: v${{ steps.new.outputs.version }}"
          body: |
            Bumps version from ${{ steps.current.outputs.version }} to ${{ steps.new.outputs.version }}.

            **Changes included:**
            - Version bump in `Cargo.toml`
            - Updated `CHANGELOG.md` (auto-generated from commits)

            Once merged, this will automatically:
            - Create git tag `v${{ steps.new.outputs.version }}`
            - Build binaries for Linux, macOS, Windows
            - Publish to crates.io
            - Create GitHub Release with binaries

  publish:
    name: Publish Release
    if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/v')
    runs-on: ubuntu-latest
    permissions:
      contents: write
    outputs:
      version: ${{ steps.version.outputs.version }}
    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable

      - name: Get version from Cargo.toml
        id: version
        run: |
          VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Create and push tag
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git tag "v${{ steps.version.outputs.version }}"
          git push origin "v${{ steps.version.outputs.version }}"

      - name: Publish to crates.io
        run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: v${{ steps.version.outputs.version }}
          name: v${{ steps.version.outputs.version }}
          generate_release_notes: true
          draft: false

  build-binaries:
    name: Build ${{ matrix.target }}
    needs: [publish]
    if: |
      always() &&
      (needs.publish.result == 'success' ||
       (github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'build-binaries' && github.event.inputs.version != ''))
    runs-on: ${{ matrix.os }}
    permissions:
      contents: write
    strategy:
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
          - target: aarch64-unknown-linux-gnu
            os: ubuntu-24.04-arm
          - target: x86_64-apple-darwin
            os: macos-15-intel
          - target: aarch64-apple-darwin
            os: macos-latest
          - target: x86_64-pc-windows-msvc
            os: windows-latest

    steps:
      - uses: actions/checkout@v4
        with:
          ref: v${{ needs.publish.outputs.version || github.event.inputs.version }}

      - name: Set version
        id: version
        shell: bash
        run: echo "version=${{ needs.publish.outputs.version || github.event.inputs.version }}" >> $GITHUB_OUTPUT

      - name: Install dependencies (Linux)
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install -y libssl-dev pkg-config

      - uses: dtolnay/rust-toolchain@stable

      - name: Build
        run: cargo build --release

      - name: Package binary (unix)
        if: runner.os != 'Windows'
        run: |
          cd target/release
          tar -czvf ../../tuicr-${{ steps.version.outputs.version }}-${{ matrix.target }}.tar.gz tuicr

      - name: Package binary (windows)
        if: runner.os == 'Windows'
        run: |
          cd target/release
          7z a ../../tuicr-${{ steps.version.outputs.version }}-${{ matrix.target }}.zip tuicr.exe

      - name: Upload to release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: v${{ steps.version.outputs.version }}
          files: |
            tuicr-*.tar.gz
            tuicr-*.zip
