name: CI

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

jobs:
  # Fast check to ensure all version files are in sync
  check-version-consistency:
    name: Check version consistency
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Check all versions match
        run: ./scripts/check-versions.sh

  # Fast check to catch accidental .beads/issues.jsonl changes from contributors
  check-no-beads-changes:
    name: Check for .beads changes
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Check for .beads/issues.jsonl changes
        run: |
          if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q "^\.beads/issues\.jsonl$"; then
            echo "This PR includes changes to .beads/issues.jsonl"
            echo ""
            echo "This file is the project's issue database and should not be modified in PRs."
            echo ""
            echo "To fix, run:"
            echo "  git checkout origin/main -- .beads/issues.jsonl"
            echo "  git commit --amend"
            echo "  git push --force"
            echo ""
            exit 1
          fi
          echo "No .beads/issues.jsonl changes detected"

  # Cross-platform test matrix (Linux/macOS only - Windows uses smoke tests)
  test:
    name: Test (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest]
        include:
          # Linux: full test suite with coverage
          - os: ubuntu-latest
            coverage: true
            test-flags: '-v -race -short -coverprofile=coverage.out'
          # macOS: full test suite, no coverage (faster)
          - os: macos-latest
            coverage: false
            test-flags: '-v -race -short'
    steps:
      - uses: actions/checkout@v6

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.24'

      - name: Configure Git
        run: |
          git config --global user.name "CI Bot"
          git config --global user.email "ci@beads.test"

      - name: Build
        run: go build -v ./cmd/bd

      - name: Test
        run: go test ${{ matrix.test-flags }} ./...

      - name: Check coverage threshold
        if: matrix.coverage
        run: |
          COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
          MIN_COVERAGE=42
          WARN_COVERAGE=55
          echo "Coverage: $COVERAGE%"
          if (( $(echo "$COVERAGE < $MIN_COVERAGE" | bc -l) )); then
            echo "Coverage is below ${MIN_COVERAGE}% threshold"
            exit 1
          elif (( $(echo "$COVERAGE < $WARN_COVERAGE" | bc -l) )); then
            echo "Coverage is below ${WARN_COVERAGE}% (warning threshold)"
          else
            echo "Coverage meets threshold"
          fi

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        if: matrix.coverage && success()
        with:
          file: ./coverage.out
          fail_ci_if_error: false

  # Windows smoke tests only - full test suite times out (see bd-bmev)
  # Linux/macOS run comprehensive tests; Windows just verifies binary works
  test-windows:
    name: Test (Windows - smoke)
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v6

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.24'

      - name: Configure Git
        run: |
          git config --global user.name "CI Bot"
          git config --global user.email "ci@beads.test"

      - name: Build
        run: go build -v -o bd.exe ./cmd/bd

      - name: Smoke test - version
        run: ./bd.exe version

      - name: Smoke test - init and CRUD
        run: |
          ./bd.exe init --quiet --prefix smoke
          $output = ./bd.exe create --title "Windows smoke test" --type task
          $id = ($output | Select-String -Pattern "smoke-\w+").Matches.Value
          echo "Created issue: $id"
          ./bd.exe list
          ./bd.exe show $id
          ./bd.exe update $id --status in_progress
          ./bd.exe close $id
          echo "All smoke tests passed!"

  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.24'

      - name: golangci-lint
        uses: golangci/golangci-lint-action@v9
        with:
          version: latest
          args: --timeout=5m

  test-nix:
    name: Test Nix Flake
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: cachix/install-nix-action@v31
        with:
          nix_path: nixpkgs=channel:nixos-unstable
      - name: Run bd help via Nix
        run: |
          export BEADS_DB="$PWD/.ci-beads/beads.db"
          mkdir -p "$(dirname "$BEADS_DB")"
          rm -rf .beads
          nix run .#default -- --db "$BEADS_DB" init --quiet --prefix ci
          nix run .#default -- --db "$BEADS_DB" > help.txt
      - name: Verify help text
        run: |
          FIRST_LINE=$(head -n 1 help.txt)
          EXPECTED="Issues chained together like beads. A lightweight issue tracker with first-class dependency support."
          if [ "$FIRST_LINE" != "$EXPECTED" ]; then
            echo "First line of help.txt doesn't match expected output"
            echo "Expected: $EXPECTED"
            echo "Got: $FIRST_LINE"
            exit 1
          fi
          echo "Help text first line is correct"
