name: E2E Tests
on:
  push:
    branches: [ main ]
    paths-ignore:
      - "docs/**"
      - "**.md"
      - ".github/**"
  pull_request:
    branches: [ main, breaking/** ]
    paths-ignore:
      - "docs/**"
      - "**.md"
      - ".github/**"

permissions:
  contents: read
  actions: write
  id-token: write

jobs:
  test:
    if: github.event.pull_request.head.ref != 'i18n_crowdin'
    runs-on: depot-ubuntu-24.04-32
    strategy:
      fail-fast: false
      matrix:
        include:
          - db: sqlite
            storage: filesystem
          - db: postgres
            storage: filesystem
          - db: sqlite
            storage: s3
          - db: sqlite
            storage: database
          - db: postgres
            storage: database

    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Setup pnpm
        uses: pnpm/action-setup@v5

      - name: Setup Node.js
        uses: actions/setup-node@v6.4.0
        with:
          node-version: 24
          cache: "pnpm"

      - name: Set up Depot CLI
        uses: depot/setup-action@v1

      - name: Set up Depot Docker builder
        run: depot configure-docker

      - name: Cache Playwright Browsers
        uses: actions/cache@v5
        id: playwright-cache
        with:
          path: ~/.cache/ms-playwright
          key: ${{ runner.os }}-playwright-${{ hashFiles('pnpm-lock.yaml') }}

      - name: Cache PostgreSQL Docker image
        uses: actions/cache@v5
        id: postgres-cache
        with:
          path: /tmp/postgres-image.tar
          key: postgres-17-${{ runner.os }}
      - name: Pull and save PostgreSQL image
        if: matrix.db == 'postgres' && steps.postgres-cache.outputs.cache-hit != 'true'
        run: |
          docker pull postgres:17
          docker save postgres:17 > /tmp/postgres-image.tar
      - name: Load PostgreSQL image
        if: matrix.db == 'postgres' && steps.postgres-cache.outputs.cache-hit == 'true'
        run: docker load < /tmp/postgres-image.tar

      - name: Cache SCIM Test Server Docker image
        uses: actions/cache@v5
        id: scim-cache
        with:
          path: /tmp/scim-test-server-image.tar
          key: scim-test-server-${{ runner.os }}
      - name: Pull and save SCIM Test Server image
        if: steps.scim-cache.outputs.cache-hit != 'true'
        run: |
          docker pull ghcr.io/pocket-id/scim-test-server
          docker save ghcr.io/pocket-id/scim-test-server > /tmp/scim-test-server-image.tar
      - name: Load SCIM Test Server image
        if: steps.scim-cache.outputs.cache-hit == 'true'
        run: docker load < /tmp/scim-test-server-image.tar

      - name: Cache Localstack S3 Docker image
        if: matrix.storage == 's3'
        uses: actions/cache@v5
        id: s3-cache
        with:
          path: /tmp/localstack-s3-image.tar
          key: localstack-4.14.0-${{ runner.os }}
      - name: Pull and save Localstack S3 image
        if: matrix.storage == 's3' && steps.s3-cache.outputs.cache-hit != 'true'
        run: |
          docker pull localstack/localstack:4.14.0
          docker save localstack/localstack:4.14.0 > /tmp/localstack-s3-image.tar
      - name: Load Localstack S3 image
        if: matrix.storage == 's3' && steps.s3-cache.outputs.cache-hit == 'true'
        run: docker load < /tmp/localstack-s3-image.tar

      - name: Install test dependencies
        run: pnpm --filter pocket-id-tests install --frozen-lockfile

      - name: Install Playwright Browsers
        working-directory: ./tests
        if: steps.playwright-cache.outputs.cache-hit != 'true'
        run: pnpm exec playwright install --with-deps chromium

      - name: Run Docker containers
        working-directory: ./tests/setup
        run: |
          DOCKER_COMPOSE_FILE=docker-compose.yml

          cat > .env <<EOF
          FILE_BACKEND=${{ matrix.storage }}
          SCIM_SERVICE_PROVIDER_URL=http://localhost:18123/v2
          SCIM_SERVICE_PROVIDER_URL_INTERNAL=http://scim-test-server:8080/v2
          EOF

          if [ "${{ matrix.db }}" = "postgres" ]; then
            DOCKER_COMPOSE_FILE=docker-compose-postgres.yml
          elif [ "${{ matrix.storage }}" = "s3" ]; then
            DOCKER_COMPOSE_FILE=docker-compose-s3.yml
          fi

          docker compose -f "$DOCKER_COMPOSE_FILE" up -d --build

          {
            LOG_FILE="/tmp/backend.log"
            while true; do
              CID=$(docker compose -f "$DOCKER_COMPOSE_FILE" ps -q pocket-id)
              if [ -n "$CID" ]; then
                echo "[$(date)] Attaching logs for $CID" >> "$LOG_FILE"
                docker logs -f --since=0 "$CID" >> "$LOG_FILE" 2>&1
              else
                echo "[$(date)] Container not yet running…" >> "$LOG_FILE"
              fi
              sleep 1
            done
          } &

      - name: Run Playwright tests
        working-directory: ./tests
        run: pnpm exec playwright test

      - name: Upload Test Report
        uses: actions/upload-artifact@v7
        if: always() && github.event.pull_request.head.ref != 'i18n_crowdin'
        with:
          name: playwright-report-${{ matrix.db }}-${{ matrix.storage }}
          path: tests/.report
          include-hidden-files: true
          retention-days: 15

      - name: Upload Backend Test Report
        uses: actions/upload-artifact@v7
        if: always() && github.event.pull_request.head.ref != 'i18n_crowdin'
        with:
          name: backend-${{ matrix.db }}-${{ matrix.storage }}
          path: /tmp/backend.log
          include-hidden-files: true
          retention-days: 15
