name: go-backend-ci

on:
  workflow_dispatch:
  pull_request:
    paths:
      - "go-backend/**"
      - ".github/workflows/go-backend-ci.yml"
  push:
    branches:
      - main
      - develop
    paths:
      - "go-backend/**"
      - ".github/workflows/go-backend-ci.yml"

concurrency:
  group: go-backend-ci-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  check-go-backend:
    name: Check go-backend
    runs-on: ubuntu-latest
    timeout-minutes: 20

    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_DB: xtablo
          POSTGRES_USER: xtablo
          POSTGRES_PASSWORD: xtablo
        ports:
          - 5432:5432
        options: >-
          --health-cmd "pg_isready -U xtablo -d xtablo"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    defaults:
      run:
        working-directory: go-backend

    env:
      DATABASE_URL: postgres://xtablo:xtablo@127.0.0.1:5432/xtablo?sslmode=disable

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

      - name: Set up Go
        uses: actions/setup-go@v6
        with:
          go-version-file: go-backend/go.mod
          cache-dependency-path: go-backend/go.sum

      - name: Install PostgreSQL client
        run: sudo apt-get update && sudo apt-get install -y postgresql-client

      - name: Install code generation tools
        run: |
          go install github.com/a-h/templ/cmd/templ@v0.3.1001
          go install github.com/sqlc-dev/sqlc/cmd/sqlc@v1.31.1

      - name: Load database schema
        run: psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f internal/db/schema.sql

      - name: Seed database
        run: psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f internal/db/seed.sql

      - name: Generate templ and sqlc code
        run: |
          templ generate
          sqlc generate

      - name: Verify generated files are committed
        run: git diff --exit-code -- internal/db/sqlc internal/web/views

      - name: Run tests
        run: go test ./...

      - name: Build
        run: go build ./...

      - name: Smoke test app against Postgres
        run: |
          set -euo pipefail

          go run . >/tmp/go-backend.log 2>&1 &
          app_pid=$!
          trap 'kill $app_pid || true; wait $app_pid || true' EXIT

          for _ in $(seq 1 30); do
            if curl -fsS http://127.0.0.1:3000/login >/tmp/go-backend-login.html; then
              break
            fi
            sleep 1
          done

          grep -q "Se connecter à Xtablo" /tmp/go-backend-login.html

          curl -fsS \
            -D /tmp/go-backend-signup.headers \
            -o /tmp/go-backend-signup.body \
            -X POST \
            -H 'Content-Type: application/x-www-form-urlencoded' \
            --data 'email=ci-user@example.com&password=xtablo-secret' \
            http://127.0.0.1:3000/signup

          grep -qi '^Hx-Redirect: /' /tmp/go-backend-signup.headers
          test "$(psql "$DATABASE_URL" -tA -c "select count(*) from auth.users where email = 'ci-user@example.com'")" = "1"
          test "$(psql "$DATABASE_URL" -tA -c "select count(*) from public.users where email = 'ci-user@example.com'")" = "1"
          test "$(psql "$DATABASE_URL" -tA -c "select count(*) from auth.sessions where user_id = (select id from auth.users where email = 'ci-user@example.com')")" = "1"
