name: Test Suite

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

jobs:
  unit-tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.11", "3.12"]

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}

    - name: Cache dependencies
      uses: actions/cache@v3
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
        restore-keys: |
          ${{ runner.os }}-pip-

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install -r tests/requirements-test.txt

    - name: Run unit tests
      run: |
        pytest tests/unit/ -v \
          --cov=domain \
          --cov=application \
          --cov=infrastructure \
          --cov-report=xml \
          --cov-report=term-missing \
          --cov-fail-under=85 \
          --tb=short \
          --durations=10

    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v3
      with:
        file: ./coverage.xml
        flags: unit-tests
        name: codecov-umbrella

  integration-tests:
    runs-on: ubuntu-latest
    needs: unit-tests

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: "3.12"

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install -r tests/requirements-test.txt

    - name: Run integration tests
      run: |
        pytest tests/integration/ -v \
          --tb=short \
          --maxfail=5 \
          --timeout=300

    - name: Archive test artifacts
      if: failure()
      uses: actions/upload-artifact@v3
      with:
        name: integration-test-artifacts
        path: |
          tests/integration/logs/
          tests/integration/outputs/

  e2e-tests:
    runs-on: ubuntu-latest
    needs: [unit-tests, integration-tests]

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: "3.12"

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install -r tests/requirements-test.txt

    - name: Run end-to-end tests (non-slow)
      run: |
        pytest tests/e2e/ -v \
          -m "not slow" \
          --tb=short \
          --maxfail=3 \
          --timeout=600

    - name: Run smoke tests
      run: |
        pytest tests/ -v \
          -m "smoke" \
          --tb=short \
          --timeout=120

  performance-tests:
    runs-on: ubuntu-latest
    needs: [unit-tests, integration-tests]
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: "3.12"

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install -r tests/requirements-test.txt

    - name: Run performance tests
      run: |
        pytest tests/e2e/performance/ -v \
          -m "performance" \
          --tb=short \
          --timeout=1200

    - name: Archive performance results
      uses: actions/upload-artifact@v3
      with:
        name: performance-results
        path: |
          performance-results.json
          performance-charts/

  code-quality:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: "3.12"

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r tests/requirements-test.txt

    - name: Run flake8
      run: |
        flake8 domain/ application/ infrastructure/ --count --select=E9,F63,F7,F82 --show-source --statistics
        flake8 domain/ application/ infrastructure/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

    - name: Run mypy
      run: |
        mypy domain/ application/ infrastructure/ --ignore-missing-imports

    - name: Check code formatting with black
      run: |
        black --check domain/ application/ infrastructure/

    - name: Check import sorting with isort
      run: |
        isort --check-only domain/ application/ infrastructure/

  security-scan:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: "3.12"

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install safety bandit

    - name: Run safety check
      run: |
        pip freeze | safety check --json

    - name: Run bandit security linter
      run: |
        bandit -r domain/ application/ infrastructure/ -f json -o bandit-results.json

    - name: Upload security scan results
      uses: actions/upload-artifact@v3
      with:
        name: security-scan-results
        path: |
          bandit-results.json

  test-summary:
    runs-on: ubuntu-latest
    needs: [unit-tests, integration-tests, e2e-tests, code-quality, security-scan]
    if: always()

    steps:
    - name: Check test results
      run: |
        echo "Unit Tests: ${{ needs.unit-tests.result }}"
        echo "Integration Tests: ${{ needs.integration-tests.result }}"
        echo "E2E Tests: ${{ needs.e2e-tests.result }}"
        echo "Code Quality: ${{ needs.code-quality.result }}"
        echo "Security Scan: ${{ needs.security-scan.result }}"

        if [[ "${{ needs.unit-tests.result }}" == "failure" ||
              "${{ needs.integration-tests.result }}" == "failure" ||
              "${{ needs.e2e-tests.result }}" == "failure" ]]; then
          echo "❌ Test suite failed"
          exit 1
        else
          echo "✅ Test suite passed"
        fi

    - name: Update status badge
      if: github.ref == 'refs/heads/main'
      run: |
        # This would update a status badge in the README
        echo "Test suite status: PASSING" > test-status.txt

    - name: Upload test summary
      uses: actions/upload-artifact@v3
      with:
        name: test-summary
        path: test-status.txt