name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - uses: https://git.johnogle.info/johno/gitea-actions/nix-setup@v1

      - name: Check flake
        run: nix flake check
        env:
          NIX_CONFIG: "access-tokens = git.johnogle.info=${{ secrets.GITEA_ACCESS_TOKEN }}"

  build-and-cache:
    runs-on: ubuntu-latest
    needs: check
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v6

      - uses: https://git.johnogle.info/johno/gitea-actions/nix-setup@v1

      - name: Setup SSH for cache
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.CACHE_SSH_KEY }}" > ~/.ssh/cache_key
          chmod 600 ~/.ssh/cache_key
          ssh-keyscan -H ${{ secrets.CACHE_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true

      - name: Setup signing key
        run: |
          echo "${{ secrets.NIX_SIGNING_KEY }}" > /tmp/signing-key
          chmod 600 /tmp/signing-key

      - name: Build, sign, and cache all packages
        run: |
          PACKAGES=(
            custom-claude-code
            custom-app-launcher-server
            custom-mcrcon-rbw
            custom-tea-rbw
            custom-rclone-torbox-setup
            custom-beads
            custom-gastown
            custom-perles
            qt-pinned-jellyfin-media-player
            qt-pinned-stremio
            nix-deck-kernel
          )

          FAILED=()
          SKIPPED=()
          for pkg in "${PACKAGES[@]}"; do
            echo "::group::Building $pkg"

            # Check if package is already cached by evaluating its store path and checking the remote
            OUT_PATH=$(nix eval ".#$pkg.outPath" --raw 2>/dev/null)
            if [ -n "$OUT_PATH" ] && ssh -i ~/.ssh/cache_key ${{ secrets.CACHE_USER }}@${{ secrets.CACHE_HOST }} \
                "nix path-info '$OUT_PATH' >/dev/null 2>&1"; then
              echo "⏭ $pkg already cached ($OUT_PATH), skipping"
              SKIPPED+=("$pkg")
              echo "::endgroup::"
              continue
            fi

            # --cores 2 limits parallel jobs to reduce RAM pressure on john-endesktop
            if BUILD_OUTPUT=$(nix build ".#$pkg" --no-link --print-out-paths --cores 2 2>&1); then
              OUT_PATH=$(echo "$BUILD_OUTPUT" | grep '^/nix/store/' | tail -1)
              echo "$BUILD_OUTPUT"
              echo "Store path: $OUT_PATH"

              # Sign the closure
              nix store sign --key-file /tmp/signing-key -r "$OUT_PATH"

              # Push to cache
              nix copy --to "ssh-ng://${{ secrets.CACHE_USER }}@${{ secrets.CACHE_HOST }}?ssh-key=$HOME/.ssh/cache_key" "$OUT_PATH"

              # Create GC root to prevent garbage collection
              OUT_HASH=$(basename "$OUT_PATH" | cut -d'-' -f1)
              ssh -i ~/.ssh/cache_key ${{ secrets.CACHE_USER }}@${{ secrets.CACHE_HOST }} \
                "mkdir -p /nix/var/nix/gcroots/ci-cache && ln -sfn $OUT_PATH /nix/var/nix/gcroots/ci-cache/${OUT_HASH}"

              echo "✓ $pkg cached successfully"
            else
              echo "✗ $pkg failed to build"
              FAILED+=("$pkg")
            fi
            echo "::endgroup::"
          done

          if [ ${#SKIPPED[@]} -gt 0 ]; then
            echo "Skipped (already cached): ${SKIPPED[*]}"
          fi

          if [ ${#FAILED[@]} -gt 0 ]; then
            echo "::error::Failed packages: ${FAILED[*]}"
            exit 1
          fi
        env:
          NIX_CONFIG: "access-tokens = git.johnogle.info=${{ secrets.GITEA_ACCESS_TOKEN }}"
