name: CI Pipeline

on:
  push:
    branches: ["**"]
  pull_request:
    branches: ["main"]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    name: Test (Python ${{ matrix.python-version }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.11", "3.12"]

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

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: 'pip'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
          pip install pytest pytest-cov pytest-asyncio pytest-mock

      - name: Run tests with coverage
        run: |
          pytest --cov=. --cov-report=xml --cov-report=term-missing --cov-report=html -v

      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v4
        if: matrix.python-version == '3.12'
        with:
          file: ./coverage.xml
          flags: unittests
          name: codecov-umbrella
          fail_ci_if_error: false

      - name: Archive coverage report
        uses: actions/upload-artifact@v4
        if: matrix.python-version == '3.12'
        with:
          name: coverage-report
          path: htmlcov/
          retention-days: 7

  lint:
    name: Lint & Format Check
    runs-on: ubuntu-latest

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

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

      - name: Install linting tools
        run: |
          pip install ruff black isort mypy

      - name: Run ruff (fast Python linter)
        run: |
          ruff check . --output-format=github

      - name: Check code formatting with black
        run: |
          black --check --diff .

      - name: Check import sorting with isort
        run: |
          isort --check-only --diff .

      - name: Type check with mypy
        run: |
          mypy . --ignore-missing-imports --show-error-codes
        continue-on-error: true  # Don't fail CI on type errors initially

  security:
    name: Security Scan
    runs-on: ubuntu-latest

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

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

      - name: Install safety & bandit
        run: |
          pip install safety bandit[toml]

      - name: Check for known vulnerabilities in dependencies
        run: |
          pip install -r requirements.txt
          safety check --json || true

      - name: Run bandit security linter
        run: |
          bandit -r . -f json -o bandit-report.json || true
          bandit -r . -f screen

      - name: Upload security reports
        uses: actions/upload-artifact@v4
        with:
          name: security-reports
          path: |
            bandit-report.json
          retention-days: 30

  build:
    name: Build & Test Container
    runs-on: ubuntu-latest

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

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: false
          tags: test-build:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
          load: true

      - name: Test container starts and responds
        run: |
          docker run -d --name test-container -p 8000:8000 test-build:${{ github.sha }}
          sleep 10

          # Check if container is still running
          if [ "$(docker inspect -f '{{.State.Running}}' test-container)" != "true" ]; then
            echo "Container failed to start"
            docker logs test-container
            exit 1
          fi

          # Check health endpoint
          curl -f http://localhost:8000/health || exit 1

          docker stop test-container
          docker rm test-container

  summary:
    name: CI Summary
    runs-on: ubuntu-latest
    needs: [test, lint, security, build]
    if: always()

    steps:
      - name: Check all jobs status
        run: |
          echo "Test: ${{ needs.test.result }}"
          echo "Lint: ${{ needs.lint.result }}"
          echo "Security: ${{ needs.security.result }}"
          echo "Build: ${{ needs.build.result }}"

          if [ "${{ needs.test.result }}" != "success" ] || \
             [ "${{ needs.lint.result }}" != "success" ] || \
             [ "${{ needs.build.result }}" != "success" ]; then
            echo "❌ CI pipeline failed"
            exit 1
          fi

          echo "✅ All CI checks passed"
