name: Mirror Release to GitHub

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:

env:
  GO_VERSION: '1.25.0'
  ZIG_VERSION: '0.15.2'
  GH_MIRROR_REPO: ${{ vars.GH_MIRROR_REPO }}

jobs:
  prepare_rsync:
    name: Prepare rsync metadata
    runs-on: self-hosted
    outputs:
      matrix: ${{ steps.manifest.outputs.matrix }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Install jq
        run: |
          sudo apt-get update
          sudo apt-get install -y jq

      - name: Load rsync manifest
        id: manifest
        run: |
          MANIFEST=.gitea/rsync_manifest.json
          MATRIX=$(jq -c '
            . as $cfg
            | $cfg.platforms
            | to_entries
            | map({
                platform: .key,
                target: .value.target,
                "rsync-url": ($cfg.base_url + "/" + $cfg.version + "/" + .value.asset),
                "rsync-sha256": .value.sha256
              })
          ' "$MANIFEST")
          printf 'matrix={"include":%s}\n' "$MATRIX" >> "$GITHUB_OUTPUT"

  build-cli:
    name: Build CLI - ${{ matrix.platform }}
    needs: prepare_rsync
    runs-on: self-hosted
    strategy:
      matrix: ${{ fromJson(needs.prepare_rsync.outputs.matrix) }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Set up Zig
        uses: goto-bus-stop/setup-zig@v2
        with:
          version: ${{ env.ZIG_VERSION }}

      - name: Download static rsync
        run: |
          mkdir -p cli/src/assets
          TARGET="${{ matrix.target }}"
          OS=""
          ARCH=""
          case "$TARGET" in
            x86_64-linux-*) OS="linux"; ARCH="x86_64" ;;
            aarch64-linux-*) OS="linux"; ARCH="arm64" ;;
            x86_64-macos*) OS="darwin"; ARCH="x86_64" ;;
            aarch64-macos*) OS="darwin"; ARCH="arm64" ;;
            x86_64-windows*) OS="windows"; ARCH="x86_64" ;;
            aarch64-windows*) OS="windows"; ARCH="arm64" ;;
            *) echo "Unsupported Zig target: $TARGET"; exit 1 ;;
          esac

          RSYNC_OUT="cli/src/assets/rsync/rsync_release_${OS}_${ARCH}.bin"

          wget -O "$RSYNC_OUT" ${{ matrix.rsync-url }} || \
            curl -L -o "$RSYNC_OUT" ${{ matrix.rsync-url }}

          echo "${{ matrix.rsync-sha256 }}  $RSYNC_OUT" | sha256sum -c
          chmod +x "$RSYNC_OUT"
          ls -lh "$RSYNC_OUT"

      - name: Download SQLite amalgamation
        run: |
          TARGET="${{ matrix.target }}"
          OS=""
          ARCH=""
          case "$TARGET" in
            x86_64-linux-*) OS="linux"; ARCH="x86_64" ;;
            aarch64-linux-*) OS="linux"; ARCH="arm64" ;;
            x86_64-macos*) OS="darwin"; ARCH="x86_64" ;;
            aarch64-macos*) OS="darwin"; ARCH="arm64" ;;
            x86_64-windows*) OS="windows"; ARCH="x86_64" ;;
            aarch64-windows*) OS="windows"; ARCH="arm64" ;;
            *) echo "Unsupported Zig target: $TARGET"; exit 1 ;;
          esac

          SQLITE_VERSION="3480000"
          SQLITE_YEAR="2025"
          SQLITE_URL="https://www.sqlite.org/${SQLITE_YEAR}/sqlite-amalgamation-${SQLITE_VERSION}.zip"
          SQLITE_DIR="cli/src/assets/sqlite_${OS}_${ARCH}"

          mkdir -p "$SQLITE_DIR"

          echo "Fetching SQLite ${SQLITE_VERSION}..."
          wget -O /tmp/sqlite.zip "$SQLITE_URL" || \
            curl -L -o /tmp/sqlite.zip "$SQLITE_URL"

          unzip -q /tmp/sqlite.zip -d /tmp/
          mv /tmp/sqlite-amalgamation-${SQLITE_VERSION}/* "$SQLITE_DIR/"

          ls -lh "$SQLITE_DIR"/sqlite3.c "$SQLITE_DIR"/sqlite3.h

      - name: Build CLI
        working-directory: cli
        run: |
          zig build --release=small -Dtarget=${{ matrix.target }}
          ls -lh zig-out/bin/ml

      - name: Strip binary (Linux only)
        if: matrix.platform == 'linux-x86_64'
        working-directory: cli
        run: strip zig-out/bin/ml

      - name: Package binary
        run: |
          mkdir -p dist
          cp cli/zig-out/bin/ml dist/ml-${{ matrix.platform }}
          cd dist
          tar -czf ml-${{ matrix.platform }}.tar.gz ml-${{ matrix.platform }}
          sha256sum ml-${{ matrix.platform }}.tar.gz > ml-${{ matrix.platform }}.tar.gz.sha256

      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: ml-${{ matrix.platform }}
          path: |
            dist/ml-${{ matrix.platform }}.tar.gz
            dist/ml-${{ matrix.platform }}.tar.gz.sha256

  build-go-backends:
    name: Build Go Backends
    runs-on: self-hosted
    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Set up Go
        run: |
          REQUIRED_GO="${GO_VERSION}"
          if command -v go &> /dev/null && go version | grep -q "go${REQUIRED_GO}"; then
            echo "Go ${REQUIRED_GO} already installed - skipping download"
          else
            echo "Installing Go ${REQUIRED_GO}..."
            curl -sL "https://go.dev/dl/go${REQUIRED_GO}.linux-amd64.tar.gz" | sudo tar -C /usr/local -xzf -
            export PATH="/usr/local/go/bin:$PATH"
            echo "/usr/local/go/bin" >> $GITHUB_PATH
            echo "Go ${REQUIRED_GO} installed"
          fi
          go version

      - name: Build binaries
        run: |
          make cross-platform
          ls -lh dist/

      - name: Package binaries
        run: |
          cd dist
          for binary in fetch_ml_*; do
            if [[ -f "${binary}" ]]; then
              tar -czf "${binary}.tar.gz" "${binary}"
              sha256sum "${binary}.tar.gz" > "${binary}.tar.gz.sha256"
            fi
          done

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: go-backends
          path: |
            dist/*.tar.gz
            dist/*.sha256

  mirror-github-release:
    name: Mirror release to GitHub
    needs: [build-cli, build-go-backends]
    runs-on: self-hosted
    steps:
      - name: Validate mirror configuration
        env:
          GH_TOKEN: ${{ secrets.GH_MIRROR_TOKEN }}
        run: |
          if [ -z "${GH_MIRROR_REPO}" ]; then
            echo "Missing required variable GH_MIRROR_REPO (expected like 'jfraeysd/fetch_ml')"
            exit 1
          fi
          if [ -z "${GH_TOKEN}" ]; then
            echo "Missing required secret GH_MIRROR_TOKEN"
            exit 1
          fi

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

      - name: Prepare release assets
        run: |
          mkdir -p release
          cp artifacts/ml-*/ml-*.tar.gz* release/
          cp artifacts/go-backends/*.tar.gz* release/

          cd release
          sha256sum *.tar.gz > checksums.txt
          ls -lh

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          repository: ${{ env.GH_MIRROR_REPO }}
          files: release/*
          generate_release_notes: true
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GH_MIRROR_TOKEN }}
