name: Main CI/CD Pipeline

# This is the main orchestrator workflow that runs CI first,
# then runs other workflows only if CI passes.
# Restarted: 2025-01-13

on:
  push:
    branches: [ main, master, develop ]
  pull_request:
    branches: [ main, master, develop ]

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1
  CI: true
  SKIP_SLOW_TESTS: true
  RUST_MIN_STACK: 8388608

defaults:
  run:
    shell: bash

jobs:
  # STAGE 1: CI - This must pass before anything else runs
  ci:
    name: CI Tests
    runs-on: ubuntu-22.04
    outputs:
      tests-passed: ${{ steps.tests.outputs.passed }}
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy
      
      - name: Install Deno
        uses: denoland/setup-deno@v2
        with:
          deno-version: v2.x
      
      - name: Install cargo-llvm-cov
        uses: taiki-e/install-action@cargo-llvm-cov
      
      - name: Install cargo-nextest
        uses: taiki-e/install-action@cargo-nextest
      
      - name: Install shellcheck
        run: |
          sudo apt-get update
          sudo apt-get install -y shellcheck
      
      - name: Setup Rust cache
        uses: Swatinem/rust-cache@v2
        with:
          workspaces: ". -> target"
          cache-on-failure: true
          shared-key: "ci"
      
      - name: Free disk space
        run: |
          echo "=== Before cleanup ==="
          df -h
          
          # Remove pre-installed software we don't need
          sudo apt-get clean
          sudo rm -rf /usr/share/dotnet
          sudo rm -rf /opt/ghc
          sudo rm -rf /usr/local/share/boost
          sudo rm -rf "$AGENT_TOOLSDIRECTORY"
          sudo rm -rf /usr/local/.ghcup
          
          # Clean docker images
          docker rmi $(docker images -q) 2>/dev/null || true
          
          # Clean apt cache
          sudo apt-get autoremove -y
          sudo apt-get autoclean -y
          
          echo "=== After cleanup ==="
          df -h
      
      - name: Run CI pipeline
        id: tests
        timeout-minutes: 90
        run: |
          make format
          make lint
          make check
          cargo build --release --manifest-path Cargo.toml --bin pmat
          
          # Validate timeout feature functionality (Toyota Way quality gate)
          echo "🔧 Validating timeout feature as mandatory quality gate..."
          ./scripts/validate-timeout-feature.sh
          
          make test
          echo "passed=true" >> $GITHUB_OUTPUT
      
      - name: Upload binary artifact
        uses: actions/upload-artifact@v4
        with:
          name: pmat-linux
          path: target/release/pmat
        if: success()
      
      - name: Upload coverage report
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report
          path: coverage/
        if: always()

  # STAGE 2: Additional checks - only run if CI passes
  security-audit:
    name: Security Audit
    needs: ci
    if: needs.ci.result == 'success'
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
      
      - name: Install cargo-audit
        uses: taiki-e/install-action@cargo-audit
      
      - name: Run security audit
        run: make audit

  code-quality:
    name: Code Quality
    needs: ci
    if: needs.ci.result == 'success'
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy
      
      - name: Install Deno
        uses: denoland/setup-deno@v2
        with:
          deno-version: v2.x
      
      # Skip slow validation checks for now
      # - name: Check documentation
      #   run: make validate-docs
      
      # - name: Check naming conventions
      #   run: make validate-naming
      
      # - name: Validate GitHub Actions
      #   run: make test-actions

  property-tests:
    name: Property Tests
    needs: ci
    if: needs.ci.result == 'success'
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
      
      - name: Setup Rust cache
        uses: Swatinem/rust-cache@v2
        with:
          workspaces: ". -> target"
          cache-on-failure: true
          shared-key: "ci"
      
      - name: Free disk space
        run: |
          echo "=== Freeing disk space for property tests ==="
          sudo rm -rf /usr/share/dotnet
          sudo rm -rf /opt/ghc
          sudo rm -rf /usr/local/share/boost
          sudo rm -rf "$AGENT_TOOLSDIRECTORY"
          docker rmi $(docker images -q) 2>/dev/null || true
          df -h
      
      - name: Run property-based tests
        run: |
          cd server
          # Run property tests in lib
          cargo test --lib --release -- property_tests --nocapture
          # Run the integration property test
          cargo test --test refactor_auto_property_integration --release -- --nocapture

  benchmarks:
    name: Performance Benchmarks
    needs: ci
    if: false # TEMPORARILY DISABLED for faster CI
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
      
      - name: Install shellcheck
        run: |
          sudo apt-get update
          sudo apt-get install -y shellcheck
      
      - name: Setup Rust cache
        uses: Swatinem/rust-cache@v2
        with:
          workspaces: ". -> target"
          cache-on-failure: true
          shared-key: "ci"
      
      - name: Run benchmarks
        run: make benchmark
      
      - name: Upload benchmark results
        uses: actions/upload-artifact@v4
        with:
          name: benchmark-results
          path: target/criterion/
        if: always()

  dependency-check:
    name: Dependency Check
    needs: ci
    if: needs.ci.result == 'success'
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
      
      - name: Setup Rust cache
        uses: Swatinem/rust-cache@v2
        with:
          workspaces: ". -> target"
          cache-on-failure: true
          shared-key: "ci"
      
      - name: Cache cargo tools
        uses: actions/cache@v4
        with:
          path: ~/.cargo/bin/cargo-outdated
          key: ${{ runner.os }}-cargo-outdated-${{ hashFiles('**/Cargo.lock') }}
      
      - name: Install cargo-outdated
        run: |
          if ! command -v cargo-outdated &> /dev/null; then
            cargo install cargo-outdated
          fi
      
      - name: Check for outdated dependencies
        run: make server-outdated > outdated.json || true
      
      - name: Upload dependency report
        uses: actions/upload-artifact@v4
        with:
          name: dependency-report
          path: outdated.json

  # STAGE 3: Slow tests - run after main CI passes with extended timeout
  slow-tests:
    name: Slow Integration Tests
    needs: ci
    if: needs.ci.result == 'success'
    runs-on: ubuntu-22.04
    timeout-minutes: 30  # Give slow tests more time
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
      
      - name: Setup Rust cache
        uses: Swatinem/rust-cache@v2
        with:
          workspaces: ". -> target"
          cache-on-failure: true
          shared-key: "ci"
      
      - name: Run MCP integration tests
        env:
          SKIP_SLOW_TESTS: false  # Override to run slow tests
          CI: false  # Override CI flag for these specific tests
        run: |
          cd server
          # Run only the MCP integration tests that need more time
          cargo test --test bin_integration --release -- --nocapture
          cargo test --test mcp_documentation_sync --release -- --nocapture

  # Final status check
  all-checks:
    name: All Checks Passed
    needs: [ci, security-audit, code-quality]
    if: always()
    runs-on: ubuntu-22.04
    steps:
      - name: Check if all required jobs passed
        run: |
          if [[ "${{ needs.ci.result }}" != "success" ]]; then
            echo "CI failed"
            exit 1
          fi
          if [[ "${{ needs.security-audit.result }}" != "success" ]]; then
            echo "Security audit failed"
            exit 1
          fi
          if [[ "${{ needs.code-quality.result }}" != "success" ]]; then
            echo "Code quality checks failed"
            exit 1
          fi
          echo "All required checks passed!"