# Woodpecker CI Security Pipeline
# Dedizierte Security-Scans fuer DevSecOps
#
# Laeuft taeglich via Cron und bei jedem PR

when:
  - event: cron
    cron: "0 3 * * *"  # Taeglich um 3:00 Uhr
  - event: pull_request

clone:
  git:
    image: woodpeckerci/plugin-git
    settings:
      depth: 1
    extra_hosts:
      - macmini:192.168.178.100

steps:
  # ========================================
  # Static Analysis
  # ========================================

  semgrep-scan:
    image: returntocorp/semgrep:latest
    commands:
      - semgrep scan --config auto --json -o semgrep-results.json . || true
      - |
        if [ -f semgrep-results.json ]; then
          echo "=== Semgrep Findings ==="
          cat semgrep-results.json | head -100
        fi
    when:
      event: [pull_request, cron]

  bandit-python:
    image: python:3.12-slim
    commands:
      - pip install --quiet bandit
      - bandit -r backend/ -f json -o bandit-results.json || true
      - |
        if [ -f bandit-results.json ]; then
          echo "=== Bandit Findings ==="
          cat bandit-results.json | head -50
        fi
    when:
      event: [pull_request, cron]

  gosec-go:
    image: securego/gosec:latest
    commands:
      - gosec -fmt json -out gosec-consent.json ./consent-service/... || true
      - gosec -fmt json -out gosec-billing.json ./billing-service/... || true
      - echo "Go Security Scan abgeschlossen"
    when:
      event: [pull_request, cron]

  # ========================================
  # Secrets Detection
  # ========================================

  gitleaks-scan:
    image: zricethezav/gitleaks:latest
    commands:
      - gitleaks detect --source . --report-format json --report-path gitleaks-report.json || true
      - |
        if [ -s gitleaks-report.json ]; then
          echo "=== WARNUNG: Potentielle Secrets gefunden ==="
          cat gitleaks-report.json
        else
          echo "Keine Secrets gefunden"
        fi

  trufflehog-scan:
    image: trufflesecurity/trufflehog:latest
    commands:
      - trufflehog filesystem . --json > trufflehog-results.json 2>&1 || true
      - echo "TruffleHog Scan abgeschlossen"

  # ========================================
  # Dependency Vulnerabilities
  # ========================================

  npm-audit:
    image: node:20-alpine
    commands:
      - cd website && npm audit --json > ../npm-audit-website.json || true
      - cd ../studio-v2 && npm audit --json > ../npm-audit-studio.json || true
      - cd ../admin-v2 && npm audit --json > ../npm-audit-admin.json || true
      - echo "NPM Audit abgeschlossen"
    when:
      event: [pull_request, cron]

  pip-audit:
    image: python:3.12-slim
    commands:
      - pip install --quiet pip-audit
      - pip-audit -r backend/requirements.txt --format json -o pip-audit-backend.json || true
      - pip-audit -r voice-service/requirements.txt --format json -o pip-audit-voice.json || true
      - echo "Pip Audit abgeschlossen"
    when:
      event: [pull_request, cron]

  go-vulncheck:
    image: golang:1.21-alpine
    commands:
      - go install golang.org/x/vuln/cmd/govulncheck@latest
      - cd consent-service && govulncheck ./... || true
      - cd ../billing-service && govulncheck ./... || true
      - echo "Go Vulncheck abgeschlossen"
    when:
      event: [pull_request, cron]

  # ========================================
  # Container Security
  # ========================================

  trivy-filesystem:
    image: aquasec/trivy:latest
    commands:
      - trivy fs --severity HIGH,CRITICAL --format json -o trivy-fs.json . || true
      - echo "Trivy Filesystem Scan abgeschlossen"
    when:
      event: cron

  # ========================================
  # SBOM Generation (taeglich)
  # ========================================

  daily-sbom:
    image: anchore/syft:latest
    commands:
      - mkdir -p sbom-reports
      - syft dir:. -o cyclonedx-json > sbom-reports/sbom-full-$(date +%Y%m%d).json
      - echo "SBOM generiert"
    when:
      event: cron

  # ========================================
  # AUTO-FIX: Dependency Vulnerabilities
  # Laeuft nur bei Cron (nightly), nicht bei PRs
  # ========================================

  auto-fix-npm:
    image: node:20-alpine
    commands:
      - apk add --no-cache git
      - |
        echo "=== Auto-Fix: NPM Dependencies ==="
        FIXES_APPLIED=0

        for dir in website studio-v2 admin-v2 h5p-service; do
          if [ -d "$dir" ] && [ -f "$dir/package.json" ]; then
            echo "Pruefe $dir..."
            cd $dir

            # Speichere Hash vor Fix
            BEFORE=$(md5sum package-lock.json 2>/dev/null || echo "none")

            # npm audit fix (ohne --force fuer sichere Updates)
            npm audit fix --package-lock-only 2>/dev/null || true

            # Pruefe ob Aenderungen
            AFTER=$(md5sum package-lock.json 2>/dev/null || echo "none")
            if [ "$BEFORE" != "$AFTER" ]; then
              echo "  -> Fixes angewendet in $dir"
              FIXES_APPLIED=$((FIXES_APPLIED + 1))
            fi

            cd ..
          fi
        done

        echo "NPM Auto-Fix abgeschlossen: $FIXES_APPLIED Projekte aktualisiert"
        echo "NPM_FIXES=$FIXES_APPLIED" >> /tmp/autofix-results.env
    when:
      event: cron

  auto-fix-python:
    image: python:3.12-slim
    commands:
      - apt-get update && apt-get install -y git
      - pip install --quiet pip-audit
      - |
        echo "=== Auto-Fix: Python Dependencies ==="
        FIXES_APPLIED=0

        for reqfile in backend/requirements.txt voice-service/requirements.txt klausur-service/backend/requirements.txt; do
          if [ -f "$reqfile" ]; then
            echo "Pruefe $reqfile..."
            DIR=$(dirname $reqfile)

            # pip-audit mit --fix (aktualisiert requirements.txt)
            pip-audit -r $reqfile --fix 2>/dev/null || true

            # Pruefe ob requirements.txt geaendert wurde
            if git diff --quiet $reqfile 2>/dev/null; then
              echo "  -> Keine Aenderungen in $reqfile"
            else
              echo "  -> Fixes angewendet in $reqfile"
              FIXES_APPLIED=$((FIXES_APPLIED + 1))
            fi
          fi
        done

        echo "Python Auto-Fix abgeschlossen: $FIXES_APPLIED Dateien aktualisiert"
        echo "PYTHON_FIXES=$FIXES_APPLIED" >> /tmp/autofix-results.env
    when:
      event: cron

  auto-fix-go:
    image: golang:1.21-alpine
    commands:
      - apk add --no-cache git
      - |
        echo "=== Auto-Fix: Go Dependencies ==="
        FIXES_APPLIED=0

        for dir in consent-service billing-service school-service edu-search ai-compliance-sdk; do
          if [ -d "$dir" ] && [ -f "$dir/go.mod" ]; then
            echo "Pruefe $dir..."
            cd $dir

            # Go mod tidy und update
            go get -u ./... 2>/dev/null || true
            go mod tidy 2>/dev/null || true

            # Pruefe ob go.mod/go.sum geaendert wurden
            if git diff --quiet go.mod go.sum 2>/dev/null; then
              echo "  -> Keine Aenderungen in $dir"
            else
              echo "  -> Updates angewendet in $dir"
              FIXES_APPLIED=$((FIXES_APPLIED + 1))
            fi

            cd ..
          fi
        done

        echo "Go Auto-Fix abgeschlossen: $FIXES_APPLIED Module aktualisiert"
        echo "GO_FIXES=$FIXES_APPLIED" >> /tmp/autofix-results.env
    when:
      event: cron

  # ========================================
  # Commit & Push Auto-Fixes
  # ========================================

  commit-security-fixes:
    image: alpine/git:latest
    commands:
      - |
        echo "=== Commit Security Fixes ==="

        # Git konfigurieren
        git config --global user.email "security-bot@breakpilot.de"
        git config --global user.name "Security Bot"
        git config --global --add safe.directory /woodpecker/src

        # Pruefe ob es Aenderungen gibt
        if git diff --quiet && git diff --cached --quiet; then
          echo "Keine Security-Fixes zum Committen"
          exit 0
        fi

        # Zeige was geaendert wurde
        echo "Geaenderte Dateien:"
        git status --short

        # Stage alle relevanten Dateien
        git add -A \
          */package-lock.json \
          */requirements.txt \
          */go.mod \
          */go.sum \
          2>/dev/null || true

        # Commit erstellen
        TIMESTAMP=$(date +%Y-%m-%d)
        git commit -m "fix(security): auto-fix vulnerable dependencies [$TIMESTAMP]

        Automatische Sicherheitsupdates durch CI/CD Pipeline:
        - npm audit fix fuer Node.js Projekte
        - pip-audit --fix fuer Python Projekte
        - go get -u fuer Go Module

        Co-Authored-By: Security Bot <security-bot@breakpilot.de>" || echo "Nichts zu committen"

        # Push zum Repository
        git push origin HEAD:main || echo "Push fehlgeschlagen - manueller Review erforderlich"

        echo "Security-Fixes committed und gepusht"
    when:
      event: cron
      status: success

  # ========================================
  # Report to Dashboard
  # ========================================

  update-security-dashboard:
    image: curlimages/curl:latest
    commands:
      - |
        curl -X POST "http://backend:8000/api/security/scan-results" \
          -H "Content-Type: application/json" \
          -d "{
            \"scan_type\": \"daily\",
            \"timestamp\": \"$(date -Iseconds)\",
            \"tools\": [\"semgrep\", \"bandit\", \"gosec\", \"gitleaks\", \"trivy\"]
          }" || true
    when:
      status: [success, failure]
      event: cron
