# =============================================================================
# REUSABLE WORKFLOW: Code Validation Suite
# PURPOSE: Run all quality checks (audit, typecheck, lint, format, test)
# USAGE: Called by PR and main workflows for consistent validation
# OUTPUTS: Coverage reports when requested
# =============================================================================

name: Reusable Validate

on:
  workflow_call:
    inputs:
      node-version:
        description: 'Node.js version (should match package.json engines.node)'
        type: string
        default: '22' # UPDATE: When upgrading Node.js
      pnpm-version:
        description: 'pnpm version (should match package.json packageManager)'
        type: string
        default: '10.17.0' # UPDATE: When upgrading pnpm
      validate-changesets:
        description: 'validate that a changeset exists on the branch'
        type: boolean
        default: false
    secrets:
      SONAR_TOKEN:
        description: 'SonarCloud authentication token'
        required: true

# EXAMPLE USAGE:
# jobs:
#   validate:
#     uses: ./.github/workflows/reusable-validate.yml
#     with:
#       upload-coverage: true  # For PRs to show coverage

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Full history for accurate analysis

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: ${{ inputs.pnpm-version }}
          run_install: false
          standalone: true

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
          cache: pnpm # Cache dependencies for speed

      - name: Install dependencies
        # Ensures exact versions from lock file
        # FAILS IF: Lock file out of sync with package.json
        run: pnpm install --frozen-lockfile

      - name: Tests with coverage
        # Run test suite with coverage
        # Coverage enforces 80% minimum threshold for all metrics
        # FAILS IF: Tests fail or coverage below 80% (when coverage enabled)
        # To debug: Check test output and coverage/index.html
        run: pnpm test:coverage

      - name: SonarQube Scan
        uses: SonarSource/sonarqube-scan-action@v6
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

      - name: Upload coverage
        # Make coverage reports available for review
        # Download from Actions tab to view detailed HTML report
        uses: actions/upload-artifact@v4
        with:
          name: coverage-${{ github.sha }}
          path: coverage/
          retention-days: 7 # Keep for a week for PR reviews

  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Full history for accurate analysis

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: ${{ inputs.pnpm-version }}
          run_install: false
          standalone: true

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
          cache: pnpm # Cache dependencies for speed

      - name: Install dependencies
        # Ensures exact versions from lock file
        # FAILS IF: Lock file out of sync with package.json
        run: pnpm install --frozen-lockfile

      # =============================================================================
      # VALIDATION CHECKS
      # All checks run in sequence to provide clear failure messages
      # =============================================================================

      - name: Type checking
        # Validate TypeScript types without emitting files
        # FAILS IF: Type errors in any .ts file
        # To debug: Run 'pnpm typecheck' locally for detailed errors
        run: pnpm typecheck

      - name: Linting
        # Run ESLint with type-aware rules
        # FAILS IF: Linting errors (not warnings)
        # To fix: Run 'pnpm lint:fix' for auto-fixable issues
        run: pnpm lint

      - name: Format checking
        # Verify code follows Prettier formatting
        # FAILS IF: Any file not formatted
        # To fix: Run 'pnpm format:fix' to auto-format
        run: pnpm format

      - name: Install actionlint
        # Install actionlint for workflow validation
        # Uses the official installer script from rhysd/actionlint
        run: |
          echo "Installing actionlint..."
          bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
          echo "${PWD}" >> $GITHUB_PATH

      - name: Workflow linting
        # Validate GitHub Actions workflow files
        # FAILS IF: Workflow syntax errors or issues found
        # To debug: Run 'pnpm lint:workflows' locally
        run: pnpm lint:workflows

      - name: Fetch main branch for changesets
        if: inputs.validate-changesets
        # Need main branch to compare changesets
        run: git fetch origin main:main

      - name: Changeset status
        if: inputs.validate-changesets
        # Validates that changesets exist for features/fixes
        # FAILS IF: feat/fix commits exist without changesets
        # To fix: Run 'pnpm changeset' and commit the generated file
        # For non-code changes: Run 'pnpm changeset --empty'
        run: pnpm changeset:status
