stages:
  - validate
  - security
  - deploy

variables:
  PYTHONUNBUFFERED: "1"
  PYTHONPYCACHEPREFIX: "/tmp/pycache"
  RUNNER_TAG: "linux"

validate:
  stage: validate
  image: python:3.14-slim
  services:
    - name: postgres:16
      alias: postgres
  variables:
    POSTGRES_DB: portal
    POSTGRES_USER: portal_user
    POSTGRES_PASSWORD: portal_password
    DATABASE_URL: "postgresql://portal_user:portal_password@postgres:5432/portal?sslmode=disable&gssencmode=disable"
  tags:
    - linux
  before_script:
    - apt-get update
    - apt-get install -y --no-install-recommends curl
    - rm -rf /var/lib/apt/lists/*
    - python -m pip install --upgrade pip
    - pip install -r requirements.txt
  script:
    - python -m py_compile kundenportal_api.py
    - bash scripts/ci/smoke_test.sh
    - |
      python - <<'PY'
      import os
      import zipfile
      from pathlib import Path

      root = Path(".")
      target = Path("release.zip")
      excludes = [
          ".git/",
          ".github/",
          ".venv/",
          "__pycache__/",
      ]
      suffix_excludes = [".log"]

      if target.exists():
          target.unlink()

      with zipfile.ZipFile(target, "w", compression=zipfile.ZIP_DEFLATED) as zf:
          for path in root.rglob("*"):
              rel = path.relative_to(root).as_posix()
              if path.is_dir():
                  continue
              if any(rel.startswith(prefix) for prefix in excludes):
                  continue
              if any(rel.endswith(sfx) for sfx in suffix_excludes):
                  continue
              zf.write(path, rel)
      print("Created release.zip")
      PY
  artifacts:
    paths:
      - release.zip
    expire_in: 1 day

security_bandit:
  stage: security
  image: python:3.14-slim
  tags:
    - linux
  before_script:
    - python -m pip install --upgrade pip
    - pip install bandit
  script:
    - bandit -q -r kundenportal_api.py scripts

security_pip_audit:
  stage: security
  image: python:3.14-slim
  tags:
    - linux
  before_script:
    - python -m pip install --upgrade pip
    - pip install pip-audit
  script:
    - pip-audit -r requirements.txt

security_gitleaks:
  stage: security
  image:
    name: zricethezav/gitleaks:v8.18.4
    entrypoint: [""]
  tags:
    - linux
  script:
    - |
      gitleaks detect --source . --no-git --redact --exit-code 1 --config .gitleaks.toml --report-format json --report-path gitleaks-report.json \
      || { cat gitleaks-report.json; exit 1; }
  artifacts:
    when: always
    paths:
      - gitleaks-report.json
    expire_in: 1 day

deploy_azure:
  stage: deploy
  image: mcr.microsoft.com/azure-cli:2.63.0
  tags:
    - linux
  needs:
    - job: validate
      artifacts: true
    - job: security_bandit
    - job: security_pip_audit
    - job: security_gitleaks
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
  script:
    - az login --service-principal --username "$AZURE_CLIENT_ID" --password "$AZURE_CLIENT_SECRET" --tenant "$AZURE_TENANT_ID"
    - az account set --subscription "$AZURE_SUBSCRIPTION_ID"
    - az webapp update --resource-group "$AZURE_RESOURCE_GROUP" --name "$AZURE_WEBAPP_NAME" --https-only true
    - az webapp config set --resource-group "$AZURE_RESOURCE_GROUP" --name "$AZURE_WEBAPP_NAME" --min-tls-version 1.2 --ftps-state Disabled
    - |
      SETTINGS=("APP_ENV=${APP_ENV:-production}")
      [ -n "${AZURE_DATABASE_URL:-}" ] && SETTINGS+=("DATABASE_URL=${AZURE_DATABASE_URL}")
      [ -n "${KP_MANAGED_PRESENTATION_SECRET:-}" ] && SETTINGS+=("KP_MANAGED_PRESENTATION_SECRET=${KP_MANAGED_PRESENTATION_SECRET}")
      [ -n "${KP_AUTH_SESSION_SECRET:-}" ] && SETTINGS+=("KP_AUTH_SESSION_SECRET=${KP_AUTH_SESSION_SECRET}")
      [ -n "${KP_CORS_ALLOW_ORIGINS:-}" ] && SETTINGS+=("KP_CORS_ALLOW_ORIGINS=${KP_CORS_ALLOW_ORIGINS}")
      [ -n "${KP_OIDC_ENABLED:-}" ] && SETTINGS+=("KP_OIDC_ENABLED=${KP_OIDC_ENABLED}")
      [ -n "${KP_OIDC_TENANT_ID:-}" ] && SETTINGS+=("KP_OIDC_TENANT_ID=${KP_OIDC_TENANT_ID}")
      [ -n "${KP_OIDC_CLIENT_ID:-}" ] && SETTINGS+=("KP_OIDC_CLIENT_ID=${KP_OIDC_CLIENT_ID}")
      [ -n "${KP_OIDC_CLIENT_SECRET:-}" ] && SETTINGS+=("KP_OIDC_CLIENT_SECRET=${KP_OIDC_CLIENT_SECRET}")
      [ -n "${KP_OIDC_REDIRECT_URI:-}" ] && SETTINGS+=("KP_OIDC_REDIRECT_URI=${KP_OIDC_REDIRECT_URI}")
      [ -n "${KP_OIDC_SCOPE:-}" ] && SETTINGS+=("KP_OIDC_SCOPE=${KP_OIDC_SCOPE}")
      [ -n "${KP_OIDC_ALLOWED_DOMAINS:-}" ] && SETTINGS+=("KP_OIDC_ALLOWED_DOMAINS=${KP_OIDC_ALLOWED_DOMAINS}")
      [ -n "${KP_OIDC_ALLOWED_USERS:-}" ] && SETTINGS+=("KP_OIDC_ALLOWED_USERS=${KP_OIDC_ALLOWED_USERS}")
      [ -n "${KP_OIDC_ADMIN_GROUP_IDS:-}" ] && SETTINGS+=("KP_OIDC_ADMIN_GROUP_IDS=${KP_OIDC_ADMIN_GROUP_IDS}")
      [ -n "${KP_OIDC_BOOTSTRAP_ADMIN:-}" ] && SETTINGS+=("KP_OIDC_BOOTSTRAP_ADMIN=${KP_OIDC_BOOTSTRAP_ADMIN}")
      [ -n "${KP_RBAC_ENFORCED:-}" ] && SETTINGS+=("KP_RBAC_ENFORCED=${KP_RBAC_ENFORCED}")
      az webapp config appsettings set \
        --resource-group "$AZURE_RESOURCE_GROUP" \
        --name "$AZURE_WEBAPP_NAME" \
        --settings "${SETTINGS[@]}"
    - |
      if [ -n "${AZURE_STARTUP_COMMAND:-}" ]; then
        az webapp config set \
          --resource-group "$AZURE_RESOURCE_GROUP" \
          --name "$AZURE_WEBAPP_NAME" \
          --startup-file "$AZURE_STARTUP_COMMAND"
      fi
    - az webapp deploy --resource-group "$AZURE_RESOURCE_GROUP" --name "$AZURE_WEBAPP_NAME" --src-path release.zip --type zip
