name: Deploy PROD

# Déclenchement MANUEL (workflow_dispatch) — jamais auto.
# 1. backup-db : mysqldump dans un artefact GitHub (rétention 90j)
# 2. deploy    : checkout du tag prod-*, build, SFTP push, migrations, healthcheck
#
# Avant de lancer ce workflow, le tag ``prod-YYYY.MM.DD-N`` doit pointer
# sur le MÊME SHA qu'un tag ``test-*`` qui a été validé en TEST. Le but
# du build once, promote N fois est de garantir que le code testé est
# strictement celui qui part en PROD.
#
# Pré-requis : Environment ``prod`` configuré avec les secrets équivalents
# en _PROD au lieu de _TEST. Le free-tier GitHub ne permet pas de Required
# Reviewers sur private repos — la gate est ici le workflow_dispatch lui-
# même + le tag prod-* nommé explicitement.

on:
  workflow_dispatch:
    inputs:
      tag:
        description: 'Tag prod-* à déployer (doit exister)'
        required: true
        type: string
      skip_backup:
        description: 'Skip DB backup (NON recommandé)'
        required: false
        type: boolean
        default: false

jobs:
  backup-db:
    name: Backup MySQL PROD
    if: ${{ !inputs.skip_backup }}
    runs-on: ubuntu-latest
    environment: prod
    timeout-minutes: 10

    steps:
      - name: Install mysql-client
        run: |
          sudo apt-get update -qq
          sudo apt-get install -y mysql-client

      - name: Dump database
        # Note: le DB host OVH n'est pas accessible depuis l'extérieur du
        # cluster sauf si l'accès distant est activé dans le panel. Si
        # mysqldump échoue ici, alternative = SSH dans un conteneur de
        # l'API et dumper depuis là. Pour aujourd'hui on tente direct.
        run: |
          mysqldump --single-transaction --quick --no-tablespaces \
            -h ${{ secrets.DB_HOST_PROD }} \
            -u ${{ secrets.DB_USER_PROD }} \
            -p${{ secrets.DB_PASS_PROD }} \
            ${{ secrets.DB_NAME_PROD }} \
            > backup-${{ inputs.tag }}.sql || {
              echo "WARNING: dump direct a échoué — vérifier l'accès distant OVH"
              echo "Fallback : dumper depuis le serveur OVH via PHP runner (TODO)"
              echo "Pour l'instant on continue sans backup, vu skip_backup pas coché"
              exit 1
            }
          ls -lh backup-${{ inputs.tag }}.sql

      - name: Upload backup as artifact
        uses: actions/upload-artifact@v4
        with:
          name: db-backup-${{ inputs.tag }}
          path: backup-${{ inputs.tag }}.sql
          retention-days: 90
          if-no-files-found: error

  deploy:
    name: Build + deploy + migrate + healthcheck
    needs: backup-db
    if: always() && (needs.backup-db.result == 'success' || inputs.skip_backup)
    runs-on: ubuntu-latest
    environment: prod
    # 180 min — voir commentaire deploy-test.yml. 1er deploy PROD lourd
    # (vendor/ entier), deploys suivants incrémentaux <5 min.
    timeout-minutes: 180

    steps:
      - name: Checkout the tag
        uses: actions/checkout@v4
        with:
          ref: ${{ inputs.tag }}

      - name: Verify tag matches prod-* convention
        run: |
          if [[ ! "${{ inputs.tag }}" =~ ^prod- ]]; then
            echo "Tag must start with prod-* (got: ${{ inputs.tag }})"
            exit 1
          fi

      - name: Set up PHP 8.1
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.1'
          tools: composer
          coverage: none

      - name: Install production dependencies
        run: composer install --no-dev --optimize-autoloader --no-interaction --no-progress

      - name: Write version.json
        run: |
          cat > version.json <<EOF
          {
            "sha": "$(git rev-parse --short HEAD)",
            "tag": "${{ inputs.tag }}",
            "date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
            "actor": "$GITHUB_ACTOR"
          }
          EOF
          cat version.json

      - name: Deploy to OVH via SFTP
        uses: SamKirkland/FTP-Deploy-Action@v4.3.5
        with:
          server: ${{ secrets.OVH_HOST }}
          username: ${{ secrets.OVH_USER_PROD }}
          password: ${{ secrets.OVH_PASS_PROD }}
          protocol: ftp
          local-dir: ./
          server-dir: /api/
          exclude: |
            **/.git*
            **/.git*/**
            tests/**
            phpunit.xml*
            .env*
            node_modules/**
            **/.github/**
            **/Dockerfile*
            **/docker-compose*
            **/*.md
            **/database/**
            run_tests.sh

      - name: Run migrations
        run: |
          echo "→ Apply pending migrations sur api.spixer.fr"
          response=$(curl -fsSL -w "\n__HTTP__:%{http_code}" \
            -X POST \
            --data "tag=${{ inputs.tag }}&mode=apply" \
            "https://api.spixer.fr/_internal/run-migrations.php?token=${{ secrets.MIGRATION_TOKEN_PROD }}" \
            -m 60)
          echo "$response"
          http_code=$(echo "$response" | tail -1 | sed 's/.*__HTTP__://')
          if [ "$http_code" != "200" ]; then
            echo "Migrations failed with HTTP $http_code"
            exit 1
          fi

      - name: Healthcheck
        run: |
          echo "→ Healthcheck"
          sleep 5
          response=$(curl -fsS "https://api.spixer.fr/health.php" -m 15)
          echo "$response"
          echo "$response" | grep -q '"db_status": "ok"' || (echo "DB not ok"; exit 1)

      - name: Summary
        if: always()
        run: |
          echo "### Deploy PROD" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "- Tag: \`${{ inputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
          echo "- SHA: \`$(git rev-parse --short HEAD)\`" >> $GITHUB_STEP_SUMMARY
          echo "- URL: https://api.spixer.fr/" >> $GITHUB_STEP_SUMMARY
          echo "- Health: https://api.spixer.fr/health.php" >> $GITHUB_STEP_SUMMARY
          echo "- Backup: artefact \`db-backup-${{ inputs.tag }}\` retention 90j" >> $GITHUB_STEP_SUMMARY
