name: lintasAI validate

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch: {}

# Auto-cancel superseded runs on same ref (e.g., new push to PR cancels in-flight CI).
concurrency:
  group: validate-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  # Tier 1 (fail-fast gate, ~30s): parse-all + critical file presence + manifest integrity.
  # Subsumes the old `ps-parse` job (smoke-fast already runs parser on every .ps1).
  # All heavy jobs (Pester, PSSA, smoke-setup) gate on this passing.
  fast-smoke:
    runs-on: windows-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4
      - name: Run fast smoke (parse + manifest + critical files)
        shell: pwsh
        run: |
          .\tests\smoke-fast.ps1
          if ($LASTEXITCODE -ne 0) { throw "fast-smoke failed (exit $LASTEXITCODE)" }

  # Tier 2 (parallel, gated on fast-smoke): heavier jobs.
  smoke-setup:
    runs-on: windows-latest
    needs: fast-smoke
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
        with:
          path: 'kit-source'
      - name: Smoke test setup-pola-b in temp project
        shell: pwsh
        env:
          CI: 'true'
        run: |
          $proj = Join-Path $env:RUNNER_TEMP "fake-proj"
          New-Item -ItemType Directory -Force $proj | Out-Null
          Copy-Item -Recurse kit-source "$proj\.claude-kit"
          Push-Location $proj
          try {
            & .\.claude-kit\setup-pola-b.ps1
            if ($LASTEXITCODE -ne 0) { throw "setup failed" }
            & .\.claude-kit\kit.ps1 doctor
            if ($LASTEXITCODE -ne 0) { throw "doctor failed" }
            Write-Host "smoke OK"
          } finally { Pop-Location }

  yaml-lint:
    runs-on: ubuntu-latest
    needs: fast-smoke
    timeout-minutes: 3
    steps:
      - uses: actions/checkout@v4
      - name: YAML structure
        run: |
          for f in .github/workflows/*.yml; do python -c "import yaml,sys; yaml.safe_load(open('$f'))"; done

  pester-tests:
    runs-on: windows-latest
    needs: fast-smoke
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4

      # Cache PSModules dir keyed on Pester version. Saves ~30-60s per run
      # by skipping Install-Module download when the cache restores.
      - name: Cache PowerShell modules (Pester)
        id: cache-pester
        uses: actions/cache@v4
        with:
          path: ~\Documents\PowerShell\Modules
          key: psmodules-pester-v5-${{ runner.os }}

      - name: Install Pester (cache miss)
        if: steps.cache-pester.outputs.cache-hit != 'true'
        shell: pwsh
        run: Install-Module -Name Pester -MinimumVersion 5.0 -Force -SkipPublisherCheck -Scope CurrentUser

      - name: Run tests
        shell: pwsh
        run: |
          cd $env:GITHUB_WORKSPACE
          .\tests\Run-Tests.ps1

  pssa-lint:
    runs-on: windows-latest
    needs: fast-smoke
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4

      - name: Cache PowerShell modules (PSScriptAnalyzer)
        id: cache-pssa
        uses: actions/cache@v4
        with:
          path: ~\Documents\PowerShell\Modules
          key: psmodules-pssa-${{ runner.os }}

      - name: Install PSScriptAnalyzer (cache miss)
        if: steps.cache-pssa.outputs.cache-hit != 'true'
        shell: pwsh
        run: Install-Module -Name PSScriptAnalyzer -Force -SkipPublisherCheck -Scope CurrentUser

      - name: Run PSScriptAnalyzer
        shell: pwsh
        run: |
          $results = Invoke-ScriptAnalyzer -Path . -Recurse -Severity Error,Warning -ExcludeRule PSAvoidUsingWriteHost,PSUseShouldProcessForStateChangingFunctions
          if ($results) {
              $results | Format-Table -AutoSize
              Write-Error "PSScriptAnalyzer found $($results.Count) issues"
              exit 1
          }
          Write-Host "PSScriptAnalyzer: clean"
