name: Release

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:
    inputs:
      tag:
        description: 'Tag to release (e.g., v0.4.0)'
        required: true
        type: string

permissions:
  contents: read

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
        with:
          ref: ${{ inputs.tag || github.ref }}
          fetch-depth: 0

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

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

      - name: Run tests
        run: cargo test --lib --tests

  build-unix:
    name: Build ${{ matrix.target }}
    needs: test
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            artifact_name: flux9s
            asset_name: flux9s-linux-x86_64-gnu.tar.gz
            use_tar: true

          - os: ubuntu-latest
            target: x86_64-unknown-linux-musl
            artifact_name: flux9s
            asset_name: flux9s-linux-x86_64-musl.tar.gz
            use_tar: true

          - os: macos-latest
            target: aarch64-apple-darwin
            artifact_name: flux9s
            asset_name: flux9s-macos-aarch64.tar.gz
            use_tar: true

          - os: macos-15-intel
            target: x86_64-apple-darwin
            artifact_name: flux9s
            asset_name: flux9s-macos-x86_64.tar.gz
            use_tar: true

    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
        with:
          ref: ${{ inputs.tag || github.ref }}
          fetch-depth: 0

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

      - name: Install musl tools (Linux)
        if: matrix.target == 'x86_64-unknown-linux-musl'
        run: |
          sudo apt-get update
          sudo apt-get install -y musl-tools musl-dev

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

      - name: Build (musl with vendored OpenSSL)
        if: matrix.target == 'x86_64-unknown-linux-musl'
        run: cargo build --release --target ${{ matrix.target }} --features vendored-openssl

      - name: Build (other targets)
        if: matrix.target != 'x86_64-unknown-linux-musl'
        run: cargo build --release --target ${{ matrix.target }}

      - name: Create archive (Unix)
        if: matrix.use_tar
        run: |
          tar -czf ${{ matrix.asset_name }} -C target/${{ matrix.target }}/release ${{ matrix.artifact_name }}

      - name: Upload artifact
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        with:
          name: ${{ matrix.asset_name }}
          path: ${{ matrix.asset_name }}

  build-windows:
    name: Build x86_64-pc-windows-msvc (non-blocking)
    needs: test
    continue-on-error: true
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
        with:
          ref: ${{ inputs.tag || github.ref }}
          fetch-depth: 0

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-pc-windows-msvc

      - name: Install OpenSSL (Windows)
        run: |
          vcpkg install openssl:x64-windows-static-md
          echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" >> $env:GITHUB_ENV
          echo "OPENSSL_DIR=$env:VCPKG_INSTALLATION_ROOT\packages\openssl_x64-windows-static-md" >> $env:GITHUB_ENV

      - name: Cache cargo registry
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ runner.os }}-x86_64-pc-windows-msvc-cargo-${{ hashFiles('Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-x86_64-pc-windows-msvc-cargo-

      - name: Build
        run: cargo build --release --target x86_64-pc-windows-msvc

      - name: Create archive
        run: |
          Compress-Archive -Path target/x86_64-pc-windows-msvc/release/flux9s.exe -DestinationPath flux9s-windows-x86_64.zip

      - name: Upload artifact
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        with:
          name: flux9s-windows-x86_64.zip
          path: flux9s-windows-x86_64.zip

  publish:
    name: Publish to crates.io
    needs: build-unix
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
        with:
          ref: ${{ inputs.tag || github.ref }}
          fetch-depth: 0

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

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

  release:
    name: Create GitHub Release
    needs: [build-unix, build-windows, publish]
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
        with:
          ref: ${{ inputs.tag || github.ref }}
          fetch-depth: 0

      - name: Extract version from tag
        id: get_version
        env:
          INPUT_TAG: ${{ inputs.tag }}
        run: |
          if [ -n "$INPUT_TAG" ]; then
            VERSION="${INPUT_TAG}"
            VERSION="${VERSION#v}"
          else
            VERSION="${GITHUB_REF#refs/tags/v}"
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "tag=v$VERSION" >> $GITHUB_OUTPUT

      - name: Download all artifacts
        uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
        with:
          path: artifacts

      - name: Create GitHub Release
        uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2
        with:
          files: artifacts/**/*
          generate_release_notes: true
          tag_name: ${{ steps.get_version.outputs.tag }}
          name: Release ${{ steps.get_version.outputs.version }}
          fail_on_unmatched_files: true
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  update-homebrew:
    name: Update Homebrew Formula
    needs: [build-unix, release]
    runs-on: ubuntu-latest
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
        with:
          path: artifacts

      - name: Extract version
        id: version
        run: |
          VERSION=${GITHUB_REF#refs/tags/v}
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Calculate checksums
        id: checksums
        run: |
          MACOS_INTEL_SHA=$(shasum -a 256 artifacts/flux9s-macos-x86_64.tar.gz/flux9s-macos-x86_64.tar.gz | cut -d' ' -f1)
          MACOS_ARM_SHA=$(shasum -a 256 artifacts/flux9s-macos-aarch64.tar.gz/flux9s-macos-aarch64.tar.gz | cut -d' ' -f1)
          LINUX_MUSL_SHA=$(shasum -a 256 artifacts/flux9s-linux-x86_64-musl.tar.gz/flux9s-linux-x86_64-musl.tar.gz | cut -d' ' -f1)

          echo "macos_intel_sha=$MACOS_INTEL_SHA" >> $GITHUB_OUTPUT
          echo "macos_arm_sha=$MACOS_ARM_SHA" >> $GITHUB_OUTPUT
          echo "linux_musl_sha=$LINUX_MUSL_SHA" >> $GITHUB_OUTPUT

      - name: Checkout homebrew-tap
        uses: actions/checkout@v4
        with:
          repository: dgunzy/homebrew-tap
          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
          path: homebrew-tap

      - name: Update formula
        run: |
          cd homebrew-tap
          VERSION=${{ steps.version.outputs.version }}

          cat > flux9s.rb << 'EOF'
          class Flux9s < Formula
            desc "K9s-inspired terminal UI for monitoring Flux GitOps resources"
            homepage "https://github.com/dgunzy/flux9s"
            version "${{ steps.version.outputs.version }}"
            license "Apache-2.0"

            on_macos do
              if Hardware::CPU.intel?
                url "https://github.com/dgunzy/flux9s/releases/download/v${{ steps.version.outputs.version }}/flux9s-macos-x86_64.tar.gz"
                sha256 "${{ steps.checksums.outputs.macos_intel_sha }}"
              elsif Hardware::CPU.arm?
                url "https://github.com/dgunzy/flux9s/releases/download/v${{ steps.version.outputs.version }}/flux9s-macos-aarch64.tar.gz"
                sha256 "${{ steps.checksums.outputs.macos_arm_sha }}"
              end
            end

            on_linux do
              if Hardware::CPU.intel?
                url "https://github.com/dgunzy/flux9s/releases/download/v${{ steps.version.outputs.version }}/flux9s-linux-x86_64-musl.tar.gz"
                sha256 "${{ steps.checksums.outputs.linux_musl_sha }}"
              end
            end

            def install
              bin.install "flux9s"
            end

            test do
              system "#{bin}/flux9s", "--version"
            end
          end
          EOF

      - name: Commit and push
        run: |
          cd homebrew-tap
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add flux9s.rb
          git commit -m "Update flux9s to v${{ steps.version.outputs.version }}"
          git push
