name: CI
# CI Wakdo - Forgejo Actions (runner stark-wakdo, label `docker`).
# Strategie solo dev : PR obligatoire ; l'auto-merge NATIF Forgejo
# (merge_when_checks_succeed, programme a l'ouverture de la PR) fusionne en squash
# des que les checks requis passent. Pas de job de merge dans le workflow.
#
# Etat des jobs selon la phase projet :
#   - secret-scan : fonctionnel des maintenant (gitleaks scanne tout le depot)
#   - php-lint    : fonctionnel sur les fichiers PHP presents (stubs P1, code P2+)
#   - static-tests: PHPStan + PHPUnit GARDES - s'activent quand P2 ajoute
#                   composer.json / phpstan.neon / tests + phpunit.xml

on:
  pull_request:
    branches: [dev, main]
    types: [opened, synchronize, reopened]
  push:
    # dev/main : porte de merge. feat|fix|ci|refactor : feedback avant la PR.
    branches: [dev, main, 'feat/**', 'fix/**', 'ci/**', 'refactor/**']

jobs:
  secret-scan:
    runs-on: docker
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Install tools
        run: |
          apt-get update -qq
          apt-get install -y -qq curl ca-certificates tar >/dev/null
      - name: Install gitleaks
        run: |
          VER=8.21.2
          curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v${VER}/gitleaks_${VER}_linux_x64.tar.gz" -o /tmp/gl.tgz
          tar -xzf /tmp/gl.tgz -C /usr/local/bin gitleaks
          gitleaks version
      - name: Scan for secrets
        run: gitleaks detect --config .gitleaks.toml --redact --no-banner --verbose

  php-lint:
    runs-on: docker
    steps:
      - uses: actions/checkout@v4
      - name: Install PHP CLI
        run: |
          apt-get update -qq
          apt-get install -y -qq php-cli >/dev/null
          php --version
      - name: Lint all PHP files
        run: |
          set -eu
          files=$(find . -path ./node_modules -prune -o -name '*.php' -print)
          if [ -z "$files" ]; then echo "No PHP files yet - skip"; exit 0; fi
          echo "$files" | while IFS= read -r f; do
            [ -z "$f" ] && continue
            php -l "$f"
          done

  static-tests:
    runs-on: docker
    # COMPOSER-LESS (decision 4 / 5, PROJECT_CONTEXT.md) : PHPStan et PHPUnit
    # tournent depuis leur .phar autonome telecharge ici, jamais via Composer.
    # Versions epinglees pour des CI reproductibles (pas de "latest").
    #
    # Service MariaDB ephemere : le schema (db/migrations) et le seed (db/seeds)
    # y sont appliques, puis PHPUnit tourne avec WAKDO_DB_TESTS=1 pour que les
    # tests d'integration (tests/Integration/*DbTest) s'executent REELLEMENT.
    # Sans base, ils s'auto-skippent et le SQL porteur de securite (throttle,
    # RBAC is_active, audit in-transaction, FK) n'est jamais valide en CI.
    # Identifiants ci-dessous : ephemeres, CI uniquement, jamais des secrets.
    services:
      mariadb:
        image: mariadb:11.4
        env:
          MARIADB_ROOT_PASSWORD: root
          MARIADB_DATABASE: wakdo_test
          MARIADB_USER: wakdo
          MARIADB_PASSWORD: wakdo
    env:
      PHPUNIT_VERSION: "11.5.2"
      PHPSTAN_VERSION: "1.12.27"
      # Connexion des tests d'integration au service `mariadb` ci-dessus
      # (Database lit ces DB_* via getenv ; cf. src/app/Core/Database.php).
      WAKDO_DB_TESTS: "1"
      DB_HOST: mariadb
      DB_PORT: "3306"
      DB_NAME: wakdo_test
      DB_USER: wakdo
      DB_PASSWORD: wakdo
    steps:
      - uses: actions/checkout@v4
      - name: PHPStan (guarded)
        run: |
          set -eu
          if [ ! -f phpstan.neon ]; then
            echo "PHPStan skipped: no phpstan.neon yet (activates in P2)"
            exit 0
          fi
          echo "phpstan.neon detected - running PHPStan ${PHPSTAN_VERSION} via .phar"
          apt-get update -qq && apt-get install -y -qq php-cli php-xml php-mbstring curl ca-certificates >/dev/null
          # PHPUnit phar present pour que phpstan.neon (scanDirectories phar://phpunit.phar)
          # resolve les symboles PHPUnit\Framework\* utilises sous tests/.
          curl -sSL "https://phar.phpunit.de/phpunit-${PHPUNIT_VERSION}.phar" -o phpunit.phar
          curl -sSL "https://github.com/phpstan/phpstan/releases/download/${PHPSTAN_VERSION}/phpstan.phar" -o phpstan.phar
          php phpstan.phar --version
          # memory_limit=-1 : l'analyse parallele depasse les 128M par defaut du php-cli.
          php -d memory_limit=-1 phpstan.phar analyse --no-progress --error-format=raw
      - name: PHPUnit (guarded, avec tests d'integration DB)
        run: |
          set -eu
          if [ ! -d tests ] || [ ! -f phpunit.xml ]; then
            echo "PHPUnit skipped: no tests/ + phpunit.xml yet (activates in P2)"
            exit 0
          fi
          echo "phpunit.xml + tests/ detected - running PHPUnit ${PHPUNIT_VERSION} via .phar"
          # php-mysql = pilote pdo_mysql requis par les *DbTest ; mariadb-client
          # pour appliquer schema + seed au service mariadb.
          apt-get update -qq && apt-get install -y -qq php-cli php-xml php-mbstring php-mysql mariadb-client curl ca-certificates >/dev/null
          # Attente active que le service MariaDB reponde (en plus du lien de service).
          echo "Attente du service MariaDB ${DB_HOST}:${DB_PORT} ..."
          ready=0
          for i in $(seq 1 30); do
            if mariadb -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASSWORD}" -e "SELECT 1" "${DB_NAME}" >/dev/null 2>&1; then
              echo "MariaDB pret (tentative ${i})."; ready=1; break
            fi
            sleep 2
          done
          [ "${ready}" = 1 ] || { echo "ERREUR: MariaDB injoignable apres 60s"; exit 1; }
          # Schema (db/migrations) puis seed (db/seeds), ordre lexicographique.
          for f in db/migrations/*.sql; do
            echo "migrate $(basename "$f")"
            mariadb -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASSWORD}" "${DB_NAME}" < "$f"
          done
          for f in db/seeds/*.sql; do
            echo "seed $(basename "$f")"
            mariadb -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASSWORD}" "${DB_NAME}" < "$f"
          done
          curl -sSL "https://phar.phpunit.de/phpunit-${PHPUNIT_VERSION}.phar" -o phpunit.phar
          php phpunit.phar --version
          # --fail-on-skipped : si un *DbTest s'auto-skippe (base injoignable), la
          # CI echoue au lieu de masquer le trou derriere un vert. C'est le coeur
          # du correctif : plus aucun skip silencieux des chemins securite.
          php phpunit.phar -c phpunit.xml --fail-on-skipped

  js-tests:
    # Tests du front borne (kiosk) : node:test + jsdom, sans navigateur.
    # GARDE : ne s'active que si package.json + tests/js/ existent.
    runs-on: docker
    steps:
      - uses: actions/checkout@v4
      - name: Install Node.js 20
        run: |
          set -eu
          # Node 20 epingle via NodeSource (self-contained, comme les .phar/gitleaks)
          # plutot que l'apt bookworm (18.x, limite basse pour jsdom). Reproductible.
          apt-get update -qq && apt-get install -y -qq curl ca-certificates >/dev/null
          curl -fsSL https://deb.nodesource.com/setup_20.x | bash - >/dev/null
          apt-get install -y -qq nodejs >/dev/null
          node --version && npm --version
      - name: Install deps + run kiosk JS tests
        run: |
          set -eu
          if [ ! -f package.json ] || [ ! -d tests/js ]; then
            echo "JS tests skipped: no package.json + tests/js/ yet"
            exit 0
          fi
          # Skip le download des browsers Playwright : ce job ne fait que node:test+jsdom.
          # (@playwright/test est en devDep pour l'E2E, mais ses browsers ne servent
          # qu'a tests/e2e via le conteneur officiel.)
          PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm ci
          npm run test:js
