name: Automated Testing

on:
  push:
    branches: [main, develop]
    paths:
      - 'scripts/**'
      - '.github/workflows/test.yml'
      - 'pyproject.toml'
      - 'requirements*.txt'
  pull_request:
    branches: [main]
    paths:
      - 'scripts/**'
      - '.github/workflows/test.yml'
      - 'pyproject.toml'
      - 'requirements*.txt'

# Cancel in-progress runs for the same branch
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  pytest:
    name: Unit Tests (Python ${{ matrix.python-version }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ['3.10', '3.11', '3.12']

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python ${{ matrix.python-version }}
        run: uv python install ${{ matrix.python-version }}

      - name: Create venv and install dependencies
        run: |
          uv venv
          uv pip install -r scripts/requirements-dev.txt

      - name: Run pytest
        run: uv run pytest scripts/tests/ -v --tb=short --cov=scripts --cov-report=xml --cov-report=html
        continue-on-error: false

      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage.xml
          flags: unittests
          name: codecov-python-${{ matrix.python-version }}
          fail_ci_if_error: false
          verbose: true

      - name: Archive test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: pytest-results-${{ matrix.python-version }}
          path: |
            coverage.xml
            htmlcov/
          retention-days: 7

  lint:
    name: Code Quality (Lint & Format)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python
        run: uv python install 3.11

      - name: Create venv and install Ruff
        run: |
          uv venv
          uv pip install ruff

      - name: Ruff Format Check
        run: uv run ruff format --check scripts/
        continue-on-error: true

      - name: Ruff Lint Check
        run: uv run ruff check scripts/
        continue-on-error: true

  security:
    name: Security Scan
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python
        run: uv python install 3.11

      - name: Create venv and install Bandit
        run: |
          uv venv
          uv pip install "bandit[toml]"

      - name: Run Bandit Security Scan
        run: uv run bandit -c pyproject.toml -r scripts/ --exclude scripts/tests/ -f json -o bandit-report.json
        continue-on-error: true

      - name: Upload security report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: bandit-security-report
          path: bandit-report.json
          retention-days: 7

  type-check:
    name: Type Checking
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python
        run: uv python install 3.11

      - name: Create venv and install mypy
        run: |
          uv venv
          uv pip install -r scripts/requirements-dev.txt mypy

      - name: Run mypy
        run: uv run mypy scripts/ --ignore-missing-imports --no-implicit-optional
        continue-on-error: true

  build-epub:
    name: Build EPUB Artifact
    runs-on: ubuntu-latest
    needs: [pytest, lint, security]
    if: success()

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python
        run: uv python install 3.11

      - name: Create venv and install dependencies
        run: |
          uv venv
          uv pip install -r scripts/requirements-dev.txt

      - name: Build EPUB
        run: uv run scripts/build_epub.py

      - name: Verify EPUB Created
        run: |
          if [ -f claude-howto-guide.epub ]; then
            echo "✅ EPUB built successfully"
            ls -lh claude-howto-guide.epub
          else
            echo "❌ EPUB file not found!"
            exit 1
          fi

      - name: Upload EPUB Artifact
        uses: actions/upload-artifact@v4
        with:
          name: claude-howto-guide-epub
          path: claude-howto-guide.epub
          retention-days: 7
          compression-level: 0

  summary:
    name: Test Summary
    needs: [pytest, lint, security, type-check, build-epub]
    runs-on: ubuntu-latest
    if: always()

    steps:
      - name: Download all artifacts
        uses: actions/download-artifact@v4

      - name: Generate Summary
        run: |
          echo "# Test Summary" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "## Results" >> $GITHUB_STEP_SUMMARY
          echo "- **Unit Tests**: ${{ needs.pytest.result }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Code Quality**: ${{ needs.lint.result }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Security Scan**: ${{ needs.security.result }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Type Checking**: ${{ needs.type-check.result }}" >> $GITHUB_STEP_SUMMARY
          echo "- **EPUB Build**: ${{ needs.build-epub.result }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "## Artifacts" >> $GITHUB_STEP_SUMMARY
          echo "- pytest-results-* (coverage and test results)" >> $GITHUB_STEP_SUMMARY
          echo "- bandit-security-report (security scan JSON)" >> $GITHUB_STEP_SUMMARY
          echo "- claude-howto-guide-epub (built EPUB file)" >> $GITHUB_STEP_SUMMARY

      - name: Check if all tests passed
        if: |
          needs.pytest.result != 'success' ||
          needs.build-epub.result != 'success'
        run: |
          echo "❌ Critical tests failed"
          exit 1

      - name: All tests passed
        if: success()
        run: echo "✅ All tests passed successfully!"
