name: Quality suite

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:
    inputs:
      run_ai_review:
        description: Run the optional multimodal AI visual review
        required: false
        default: false
        type: boolean

permissions:
  contents: read

jobs:
  test:
    name: Browser, API, a11y, performance, and security
    runs-on: ubuntu-latest
    timeout-minutes: 25
    steps:
      - name: Check out repository
        uses: actions/checkout@v5

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: npm

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: pip

      - name: Install JavaScript dependencies
        run: npm ci

      - name: Install Playwright browsers
        run: npx playwright install --with-deps chromium firefox

      - name: Install Python dependencies
        run: python -m pip install -r requirements.txt

      - name: Run required quality gates
        run: npm run test:full
        env:
          CI: 'true'

      - name: Triage failed Playwright artifacts with AI
        if: failure()
        continue-on-error: true
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          OPENAI_MODEL: gpt-5.6-luna
        run: |
          if [ -z "$OPENAI_API_KEY" ]; then
            echo "OPENAI_API_KEY is not configured; skipping advisory AI triage."
            exit 0
          fi
          npm run test:ai:triage
          npm run report:index

      - name: Upload human-readable reports and debug artifacts
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: quality-reports
          path: |
            reports/
            test-results/
          if-no-files-found: warn
          retention-days: 14

  ai-visual-review:
    name: Optional multimodal AI visual review
    needs: test
    if: ${{ github.event_name == 'workflow_dispatch' && inputs.run_ai_review && needs.test.result == 'success' }}
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Check out repository
        uses: actions/checkout@v5

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Install Chromium
        run: npx playwright install --with-deps chromium

      - name: Run AI visual review
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          OPENAI_MODEL: gpt-5.6-luna
          AI_FAIL_ON: 'off'
        run: |
          if [ -z "$OPENAI_API_KEY" ]; then
            echo "::error::Add OPENAI_API_KEY as a repository secret before requesting the AI review."
            exit 1
          fi
          npm run test:ai:visual
          npm run report:index

      - name: Upload AI report and review screenshots
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: ai-qa-review
          path: reports/ai/
          if-no-files-found: warn
          retention-days: 14

  zap-baseline:
    name: Optional OWASP ZAP baseline
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Check out repository
        uses: actions/checkout@v5

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: npm

      - name: Install application dependencies
        run: npm ci --omit=dev

      - name: Start the target application
        run: |
          npm start > /tmp/quality-lab-server.log 2>&1 &
          for attempt in {1..20}; do
            curl --fail --silent http://127.0.0.1:3000/api/health && exit 0
            sleep 1
          done
          cat /tmp/quality-lab-server.log
          exit 1

      - name: Run passive ZAP baseline scan
        run: npm run scan:zap

      - name: Upload ZAP report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: zap-report
          path: reports/zap/
          if-no-files-found: warn
          retention-days: 14
