name: Test Suite

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]
  workflow_run:
    workflows: ["Deploy Development", "Deploy Production"]
    types: [completed]

jobs:
  # Pytest im laufenden backend-Container; ACCESS_LAYER + TRAINING_PLANNING Integration gegen dieselbe PostgreSQL wie Deploy (Schema via Container-Start migriert).
  pytest-backend:
    if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
    runs-on: ubuntu-latest
    steps:
      - name: Backend pytest im deployten Container
        run: |
          EVENT_NAME="${{ github.event_name }}"
          REF_NAME="${{ github.ref_name }}"
          RUN_WORKFLOW="${{ github.event.workflow_run.name }}"
          APP_DIR="/home/lars/docker/shinkan"
          COMPOSE_FILE="docker-compose.yml"

          if [ "$EVENT_NAME" = "workflow_run" ]; then
            if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then
              APP_DIR="/home/lars/docker/shinkan-dev"
              COMPOSE_FILE="docker-compose.dev-env.yml"
            fi
          elif [ "$REF_NAME" = "develop" ]; then
            APP_DIR="/home/lars/docker/shinkan-dev"
            COMPOSE_FILE="docker-compose.dev-env.yml"
          fi

          cd "$APP_DIR"
          docker compose -f "$COMPOSE_FILE" exec -T backend sh -lc "
            pip install -r /app/requirements-dev.txt &&
            cd /app &&
            ACCESS_LAYER_STRICT=1 python scripts/check_access_layer_hints.py &&
            python scripts/security_release_checks.py &&
            ACCESS_LAYER_INTEGRATION=1 TRAINING_PLANNING_INTEGRATION=1 SKIP_DB_MIGRATE=1 python -m pytest tests -m 'not slow' -ra -vv --tb=short
          "

  lint-backend:
    if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
    runs-on: ubuntu-latest
    steps:
      - name: Check backend syntax
        run: |
          EVENT_NAME="${{ github.event_name }}"
          REF_NAME="${{ github.ref_name }}"
          RUN_WORKFLOW="${{ github.event.workflow_run.name }}"
          APP_DIR="/home/lars/docker/shinkan"

          if [ "$EVENT_NAME" = "workflow_run" ]; then
            if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then
              APP_DIR="/home/lars/docker/shinkan-dev"
            fi
          elif [ "$REF_NAME" = "develop" ]; then
            APP_DIR="/home/lars/docker/shinkan-dev"
          fi

          python3 -m py_compile "$APP_DIR/backend/main.py"
          echo "✓ Backend syntax OK"

  build-frontend:
    if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
    runs-on: ubuntu-latest
    steps:
      - name: Build frontend
        run: |
          EVENT_NAME="${{ github.event_name }}"
          REF_NAME="${{ github.ref_name }}"
          RUN_WORKFLOW="${{ github.event.workflow_run.name }}"
          APP_DIR="/home/lars/docker/shinkan"

          if [ "$EVENT_NAME" = "workflow_run" ]; then
            if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then
              APP_DIR="/home/lars/docker/shinkan-dev"
            fi
          elif [ "$REF_NAME" = "develop" ]; then
            APP_DIR="/home/lars/docker/shinkan-dev"
          fi

          cd "$APP_DIR/frontend"
          npm install
          npm run build
          echo "✓ Frontend build OK"

  # Phase-0 Lastsmoke: nur k6 — eigener Job (kein Node/Playwright), klare CI-Zuordnung.
  k6-health-baseline:
    name: k6 /health Baseline
    if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
    runs-on: ubuntu-latest
    env:
      E2E_TARGET_URL: https://dev.shinkan.jinkendo.de
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: E2E-Ziel wählen (Dev über Proxy vs. Production)
        id: e2e
        run: |
          EVENT="${{ github.event_name }}"
          WF_NAME="${{ github.event.workflow_run.name }}"
          DEV_BASE="${{ env.E2E_TARGET_URL }}"
          if [ "$EVENT" = "workflow_run" ] && [ "$WF_NAME" = "Deploy Production" ]; then
            echo "mode=prod" >> $GITHUB_OUTPUT
            echo "base_url=https://shinkan.jinkendo.de" >> $GITHUB_OUTPUT
            echo "→ k6 gegen Prod-Basis."
          else
            echo "mode=dev" >> $GITHUB_OUTPUT
            echo "base_url=${DEV_BASE}" >> $GITHUB_OUTPUT
            echo "→ k6 gegen Dev (${DEV_BASE})."
          fi

      - name: Dev /health abwarten
        if: ${{ steps.e2e.outputs.mode == 'dev' }}
        run: |
          BASE="${{ steps.e2e.outputs.base_url }}"
          echo "Warte auf $BASE/health …"
          for i in $(seq 1 90); do
            if curl -sf "$BASE/health" >/dev/null 2>&1; then
              echo "Health OK (Versuch $i)"
              exit 0
            fi
            sleep 2
          done
          echo "Timeout: Dev /health nicht erreichbar — Deploy / DNS / Firewall prüfen."
          curl -v "$BASE/health" || true
          exit 1

      - name: Prod /health abwarten
        if: ${{ steps.e2e.outputs.mode == 'prod' }}
        run: |
          BASE="${{ steps.e2e.outputs.base_url }}"
          echo "Warte auf $BASE/health …"
          for i in $(seq 1 60); do
            if curl -sf "$BASE/health" >/dev/null 2>&1; then
              echo "Health OK (Versuch $i)"
              exit 0
            fi
            sleep 5
          done
          echo "Timeout: Prod /health nicht erreichbar"
          curl -v "$BASE/health" || true
          exit 1

      - name: Install k6
        run: |
          set -e
          K6_VER="v0.55.0"
          ARCH=$(uname -m)
          case "$ARCH" in
            x86_64) K6_ARCH=amd64 ;;
            aarch64|arm64) K6_ARCH=arm64 ;;
            *) echo "k6: unbekannte Architektur: $ARCH"; exit 1 ;;
          esac
          echo "Installing k6 ${K6_VER} linux-${K6_ARCH}"
          curl -sSL "https://github.com/grafana/k6/releases/download/${K6_VER}/k6-${K6_VER}-linux-${K6_ARCH}.tar.gz" -o /tmp/k6.tgz
          tar -xzf /tmp/k6.tgz -C /tmp
          sudo mv "/tmp/k6-${K6_VER}-linux-${K6_ARCH}/k6" /usr/local/bin/k6
          k6 version

      - name: k6 Health-Baseline (parallele /health)
        env:
          BASE_URL: ${{ steps.e2e.outputs.base_url }}
        run: |
          set -e
          echo "k6 gegen BASE_URL=$BASE_URL"
          k6 run scripts/load/k6-health-baseline.js
          echo "✓ k6 Health-Baseline passed"

  playwright-tests:
    if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
    runs-on: ubuntu-latest
    # Kein zusätzlicher docker-compose im Job: keine zweiten Container/Host-Ports.
    # Dev: Tests gegen bereits deployte URL (HTTPS, Reverse-Proxy). Prod: gleicher Ablauf.
    env:
      # Öffentliche Dev-Basis — muss ALLOWED_ORIGINS / Nginx entsprechen; bei anderer Domain Workflow anpassen.
      E2E_TARGET_URL: https://dev.shinkan.jinkendo.de
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: E2E-Ziel wählen (Dev über Proxy vs. Production)
        id: e2e
        run: |
          EVENT="${{ github.event_name }}"
          WF_NAME="${{ github.event.workflow_run.name }}"
          DEV_BASE="${{ env.E2E_TARGET_URL }}"
          if [ "$EVENT" = "workflow_run" ] && [ "$WF_NAME" = "Deploy Production" ]; then
            echo "mode=prod" >> $GITHUB_OUTPUT
            echo "base_url=https://shinkan.jinkendo.de" >> $GITHUB_OUTPUT
            echo "→ Prod. Secrets: E2E_PROD_TEST_EMAIL / E2E_PROD_TEST_PASSWORD."
          else
            echo "mode=dev" >> $GITHUB_OUTPUT
            echo "base_url=${DEV_BASE}" >> $GITHUB_OUTPUT
            echo "→ Deployte Dev-Umgebung (${DEV_BASE}). Secrets: E2E_DEV_TEST_EMAIL / E2E_DEV_TEST_PASSWORD."
          fi

      - name: Dev /health abwarten
        if: ${{ steps.e2e.outputs.mode == 'dev' }}
        run: |
          BASE="${{ steps.e2e.outputs.base_url }}"
          echo "Warte auf $BASE/health …"
          for i in $(seq 1 90); do
            if curl -sf "$BASE/health" >/dev/null 2>&1; then
              echo "Health OK (Versuch $i)"
              exit 0
            fi
            sleep 2
          done
          echo "Timeout: Dev /health nicht erreichbar — Deploy / DNS / Firewall prüfen."
          curl -v "$BASE/health" || true
          exit 1

      - name: Prod /health abwarten
        if: ${{ steps.e2e.outputs.mode == 'prod' }}
        run: |
          BASE="${{ steps.e2e.outputs.base_url }}"
          echo "Warte auf $BASE/health …"
          for i in $(seq 1 60); do
            if curl -sf "$BASE/health" >/dev/null 2>&1; then
              echo "Health OK (Versuch $i)"
              exit 0
            fi
            sleep 5
          done
          echo "Timeout: Prod /health nicht erreichbar"
          curl -v "$BASE/health" || true
          exit 1

      - name: Testnutzer registrieren (Dev, nur wenn möglich)
        if: ${{ steps.e2e.outputs.mode == 'dev' }}
        env:
          E2E_DEV_TEST_EMAIL: ${{ secrets.E2E_DEV_TEST_EMAIL }}
          E2E_DEV_TEST_PASSWORD: ${{ secrets.E2E_DEV_TEST_PASSWORD }}
        run: |
          BASE="${{ steps.e2e.outputs.base_url }}"
          if [ -z "$E2E_DEV_TEST_EMAIL" ] || [ -z "$E2E_DEV_TEST_PASSWORD" ]; then
            echo "(Registrierung übersprungen — Secrets E2E_DEV_* nicht gesetzt.)"
            exit 0
          fi
          curl -sf -X POST "$BASE/api/auth/register" \
            -H "Content-Type: application/json" \
            -d "{\"email\":\"${E2E_DEV_TEST_EMAIL}\",\"password\":\"${E2E_DEV_TEST_PASSWORD}\",\"name\":\"Playwright CI\"}" \
            || echo "(Register evtl. schon erfolgt oder Limits — Login-Test gilt trotzdem.)"

      - name: Install Playwright
        run: |
          npm ci || npm install
          npx playwright install --with-deps chromium

      - name: Run Playwright tests
        env:
          E2E_DEV_TEST_EMAIL: ${{ secrets.E2E_DEV_TEST_EMAIL }}
          E2E_DEV_TEST_PASSWORD: ${{ secrets.E2E_DEV_TEST_PASSWORD }}
        run: |
          set -e
          MODE="${{ steps.e2e.outputs.mode }}"
          BASE_URL="${{ steps.e2e.outputs.base_url }}"
          export PLAYWRIGHT_BASE_URL="$BASE_URL"

          if [ "$MODE" = "prod" ]; then
            export TEST_EMAIL="${{ secrets.E2E_PROD_TEST_EMAIL }}"
            export TEST_PASSWORD="${{ secrets.E2E_PROD_TEST_PASSWORD }}"
            if [ -z "$TEST_EMAIL" ] || [ -z "$TEST_PASSWORD" ]; then
              echo "Fehler: E2E_PROD_TEST_EMAIL und E2E_PROD_TEST_PASSWORD setzen."
              exit 1
            fi
          else
            export TEST_EMAIL="$E2E_DEV_TEST_EMAIL"
            export TEST_PASSWORD="$E2E_DEV_TEST_PASSWORD"
            if [ -z "$TEST_EMAIL" ] || [ -z "$TEST_PASSWORD" ]; then
              echo "Fehler: E2E_DEV_TEST_EMAIL und E2E_DEV_TEST_PASSWORD setzen (Playwright soll gegen Dev einloggen)."
              exit 1
            fi
          fi

          mkdir -p screenshots
          npx playwright test
          echo "✓ Playwright tests passed"

      - name: Upload test screenshots
        if: failure()
        # v4 ist auf Gitea (GHES-kompatibles Actions-Backend) oft nicht verfügbar
        uses: actions/upload-artifact@v3
        with:
          name: playwright-screenshots
          path: screenshots/
          retention-days: 7
