name: Release

on:
  push:
    branches: [release]

permissions:
  contents: write

env:
  CARGO_TERM_COLOR: always

jobs:
  changelog:
    name: Generate changelog
    runs-on: ubuntu-latest
    outputs:
      changelog: ${{ steps.cliff.outputs.content }}
      version: ${{ steps.version.outputs.version }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

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

      - name: Generate changelog
        id: cliff
        uses: orhun/git-cliff-action@v4
        with:
          args: --unreleased --strip header --tag v${{ steps.version.outputs.version }}
        env:
          GITHUB_REPO: ${{ github.repository }}

  build:
    name: Build (${{ matrix.target }})
    runs-on: ${{ matrix.runner }}
    needs: [changelog]
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            runner: ubuntu-latest
            cross: false
          - target: aarch64-unknown-linux-gnu
            runner: ubuntu-latest
            cross: true
          - target: x86_64-apple-darwin
            runner: macos-latest
            cross: false
          - target: aarch64-apple-darwin
            runner: macos-latest
            cross: false
          - target: x86_64-pc-windows-msvc
            runner: windows-latest
            cross: false

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Rust 1.93 stable
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: "1.93"
          targets: ${{ matrix.target }}

      - name: Cache cargo registry
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
          key: ${{ runner.os }}-${{ matrix.target }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.target }}-cargo-registry-

      - name: Install cross
        if: matrix.cross
        run: cargo install cross --locked

      - name: Build release binary (cross)
        if: matrix.cross
        run: cross build --release --target ${{ matrix.target }}

      - name: Build release binary (native)
        if: "!matrix.cross"
        run: cargo build --release --target ${{ matrix.target }}

      - name: Package binary (Unix)
        if: runner.os != 'Windows'
        run: |
          cd target/${{ matrix.target }}/release
          tar czf ../../../agcp-v${{ needs.changelog.outputs.version }}-${{ matrix.target }}.tar.gz agcp
          cd ../../..

      - name: Package binary (Windows)
        if: runner.os == 'Windows'
        shell: pwsh
        run: |
          Compress-Archive -Path "target/${{ matrix.target }}/release/agcp.exe" -DestinationPath "agcp-v${{ needs.changelog.outputs.version }}-${{ matrix.target }}.zip"

      - name: Build .deb package
        if: contains(matrix.target, 'linux')
        run: |
          case "${{ matrix.target }}" in
            x86_64-*)  DEB_ARCH="amd64" ;;
            aarch64-*) DEB_ARCH="arm64" ;;
          esac
          VERSION="${{ needs.changelog.outputs.version }}"
          PKG_DIR="agcp_${VERSION}_${DEB_ARCH}"
          mkdir -p "${PKG_DIR}/DEBIAN"
          mkdir -p "${PKG_DIR}/usr/bin"
          cp "target/${{ matrix.target }}/release/agcp" "${PKG_DIR}/usr/bin/agcp"
          chmod 755 "${PKG_DIR}/usr/bin/agcp"
          cat > "${PKG_DIR}/DEBIAN/control" << EOF
          Package: agcp
          Version: ${VERSION}
          Architecture: ${DEB_ARCH}
          Maintainer: skyline69 <skyline@noreply.codeberg.org>
          Description: Lightweight Rust proxy translating Anthropic Claude API to Google Cloud Code API
           AGCP enables Claude and Gemini models through a single Anthropic-compatible endpoint.
          Homepage: https://github.com/skyline69/agcp
          License: MIT
          Section: utils
          Priority: optional
          EOF
          # Remove leading whitespace from heredoc
          sed -i 's/^          //' "${PKG_DIR}/DEBIAN/control"
          dpkg-deb --build --root-owner-group "${PKG_DIR}"

      - name: Build .rpm package
        if: contains(matrix.target, 'linux')
        run: |
          sudo apt-get update && sudo apt-get install -y rpm
          case "${{ matrix.target }}" in
            x86_64-*)  RPM_ARCH="x86_64" ;;
            aarch64-*) RPM_ARCH="aarch64" ;;
          esac
          VERSION="${{ needs.changelog.outputs.version }}"
          mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
          # Create tarball for rpmbuild
          mkdir -p "agcp-${VERSION}"
          cp "target/${{ matrix.target }}/release/agcp" "agcp-${VERSION}/"
          tar czf "rpmbuild/SOURCES/agcp-${VERSION}.tar.gz" "agcp-${VERSION}"
          cat > rpmbuild/SPECS/agcp.spec << 'SPEC'
          Name:           agcp
          Version:        %{_version}
          Release:        1
          Summary:        Lightweight Rust proxy translating Anthropic Claude API to Google Cloud Code API
          License:        MIT
          URL:            https://github.com/skyline69/agcp
          Source0:        agcp-%{_version}.tar.gz

          %description
          AGCP enables Claude and Gemini models through a single Anthropic-compatible endpoint.

          %prep
          %setup -q

          %install
          mkdir -p %{buildroot}/usr/bin
          cp agcp %{buildroot}/usr/bin/agcp
          chmod 755 %{buildroot}/usr/bin/agcp

          %files
          /usr/bin/agcp
          SPEC
          sed -i 's/^          //' rpmbuild/SPECS/agcp.spec
          rpmbuild --define "_topdir $(pwd)/rpmbuild" \
                   --define "_version ${VERSION}" \
                   --target "${RPM_ARCH}" \
                   -bb rpmbuild/SPECS/agcp.spec
          cp rpmbuild/RPMS/${RPM_ARCH}/*.rpm "agcp-${VERSION}-1.${RPM_ARCH}.rpm"

      - name: Upload artifact (Unix)
        if: runner.os != 'Windows'
        uses: actions/upload-artifact@v4
        with:
          name: agcp-v${{ needs.changelog.outputs.version }}-${{ matrix.target }}.tar.gz
          path: agcp-v${{ needs.changelog.outputs.version }}-${{ matrix.target }}.tar.gz
          if-no-files-found: error

      - name: Upload artifact (Windows)
        if: runner.os == 'Windows'
        uses: actions/upload-artifact@v4
        with:
          name: agcp-v${{ needs.changelog.outputs.version }}-${{ matrix.target }}.zip
          path: agcp-v${{ needs.changelog.outputs.version }}-${{ matrix.target }}.zip
          if-no-files-found: error

      - name: Upload .deb artifact
        if: contains(matrix.target, 'linux')
        uses: actions/upload-artifact@v4
        with:
          name: agcp-deb-${{ matrix.target }}
          path: agcp_*.deb
          if-no-files-found: error

      - name: Upload .rpm artifact
        if: contains(matrix.target, 'linux')
        uses: actions/upload-artifact@v4
        with:
          name: agcp-rpm-${{ matrix.target }}
          path: agcp-*.rpm
          if-no-files-found: error

  release:
    name: Create GitHub release
    runs-on: ubuntu-latest
    needs: [changelog, build]
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: List artifacts
        run: ls -lR artifacts/

      - name: Create draft release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: v${{ needs.changelog.outputs.version }}
          name: agcp v${{ needs.changelog.outputs.version }}
          body: ${{ needs.changelog.outputs.changelog }}
          draft: true
          files: |
            artifacts/agcp-v${{ needs.changelog.outputs.version }}-*.tar.gz
            artifacts/agcp-v${{ needs.changelog.outputs.version }}-*.zip
            artifacts/agcp_*.deb
            artifacts/agcp-*.rpm
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Generate full changelog
        uses: orhun/git-cliff-action@v4
        with:
          args: --tag v${{ needs.changelog.outputs.version }}
        env:
          GITHUB_REPO: ${{ github.repository }}
          OUTPUT: CHANGELOG.md

      - name: Commit changelog to main
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add CHANGELOG.md
          git diff --cached --quiet && exit 0
          git commit -m "docs: update changelog for v${{ needs.changelog.outputs.version }}"
          git push origin HEAD:main
