name: CLI E2E (Docker)

on:
  push:
    branches:
      - main
  pull_request:

permissions:
  contents: read

jobs:
  cli-e2e:
    runs-on: ubuntu-latest
    timeout-minutes: 45
    env:
      COMPOSE_PROJECT_NAME: baselinr-ci
      DOCKER_NETWORK_NAME: baselinr-ci_default
      DOCKER_IMAGE_NAME: baselinr-cli-tests
      BASELINR_CONFIG_PATH: examples/config.yml
      BASELINR_DB_HOST: baselinr_postgres
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Start PostgreSQL dependency
        run: docker compose -f docker/docker-compose.yml -p $COMPOSE_PROJECT_NAME up -d postgres

      - name: Wait for PostgreSQL to become healthy
        run: |
          for i in {1..30}; do
            if docker exec baselinr_postgres pg_isready -U baselinr >/dev/null 2>&1; then
              echo "PostgreSQL is ready"
              exit 0
            fi
            echo "Waiting for PostgreSQL (attempt ${i}/30)..."
            sleep 2
          done
          echo "PostgreSQL failed to become healthy in time" >&2
          docker compose -f docker/docker-compose.yml -p $COMPOSE_PROJECT_NAME logs postgres || true
          exit 1

      - name: Build CLI image
        run: docker build -t $DOCKER_IMAGE_NAME -f docker/Dockerfile .

      - name: Run plan command
        run: |
          docker run --rm \
            --network $DOCKER_NETWORK_NAME \
              -e BASELINR_SOURCE__HOST=$BASELINR_DB_HOST \
            -e BASELINR_SOURCE__PORT=5432 \
              -e BASELINR_STORAGE__CONNECTION__HOST=$BASELINR_DB_HOST \
            -e BASELINR_STORAGE__CONNECTION__PORT=5432 \
            $DOCKER_IMAGE_NAME \
            baselinr plan --config $BASELINR_CONFIG_PATH

      - name: Run profile command twice to seed drift history
        run: |
          for run_number in 1 2; do
            echo "Starting profiling run #${run_number}"
            docker run --rm \
              --network $DOCKER_NETWORK_NAME \
              -e BASELINR_SOURCE__HOST=$BASELINR_DB_HOST \
              -e BASELINR_SOURCE__PORT=5432 \
              -e BASELINR_STORAGE__CONNECTION__HOST=$BASELINR_DB_HOST \
              -e BASELINR_STORAGE__CONNECTION__PORT=5432 \
              $DOCKER_IMAGE_NAME \
              baselinr profile --config $BASELINR_CONFIG_PATH
          done

      - name: Run drift detection command
        run: |
          docker run --rm \
            --network $DOCKER_NETWORK_NAME \
            -e BASELINR_SOURCE__HOST=$BASELINR_DB_HOST \
            -e BASELINR_SOURCE__PORT=5432 \
            -e BASELINR_STORAGE__CONNECTION__HOST=$BASELINR_DB_HOST \
            -e BASELINR_STORAGE__CONNECTION__PORT=5432 \
            $DOCKER_IMAGE_NAME \
            baselinr drift --config $BASELINR_CONFIG_PATH --dataset customers

      - name: Run query CLI commands
        run: |
          # Query recent profiling runs
          docker run --rm \
            --network $DOCKER_NETWORK_NAME \
            -e BASELINR_SOURCE__HOST=$BASELINR_DB_HOST \
            -e BASELINR_SOURCE__PORT=5432 \
            -e BASELINR_STORAGE__CONNECTION__HOST=$BASELINR_DB_HOST \
            -e BASELINR_STORAGE__CONNECTION__PORT=5432 \
            $DOCKER_IMAGE_NAME \
            baselinr query runs \
              --config $BASELINR_CONFIG_PATH \
              --limit 5 \
              --format table

          # Query drift events
          docker run --rm \
            --network $DOCKER_NETWORK_NAME \
            -e BASELINR_SOURCE__HOST=$BASELINR_DB_HOST \
            -e BASELINR_SOURCE__PORT=5432 \
            -e BASELINR_STORAGE__CONNECTION__HOST=$BASELINR_DB_HOST \
            -e BASELINR_STORAGE__CONNECTION__PORT=5432 \
            $DOCKER_IMAGE_NAME \
            baselinr query drift \
              --config $BASELINR_CONFIG_PATH \
              --table customers \
              --days 7 \
              --format table

          # Query table history
          docker run --rm \
            --network $DOCKER_NETWORK_NAME \
            -e BASELINR_SOURCE__HOST=$BASELINR_DB_HOST \
            -e BASELINR_SOURCE__PORT=5432 \
            -e BASELINR_STORAGE__CONNECTION__HOST=$BASELINR_DB_HOST \
            -e BASELINR_STORAGE__CONNECTION__PORT=5432 \
            $DOCKER_IMAGE_NAME \
            baselinr query table \
              --config $BASELINR_CONFIG_PATH \
              --table customers \
              --days 7 \
              --format json

      - name: Run status command
        run: |
          # Test basic status command
          docker run --rm \
            --network $DOCKER_NETWORK_NAME \
            -e BASELINR_SOURCE__HOST=$BASELINR_DB_HOST \
            -e BASELINR_SOURCE__PORT=5432 \
            -e BASELINR_STORAGE__CONNECTION__HOST=$BASELINR_DB_HOST \
            -e BASELINR_STORAGE__CONNECTION__PORT=5432 \
            $DOCKER_IMAGE_NAME \
            baselinr status \
              --config $BASELINR_CONFIG_PATH \
              --limit 5

          # Test status with JSON output
          docker run --rm \
            --network $DOCKER_NETWORK_NAME \
            -e BASELINR_SOURCE__HOST=$BASELINR_DB_HOST \
            -e BASELINR_SOURCE__PORT=5432 \
            -e BASELINR_STORAGE__CONNECTION__HOST=$BASELINR_DB_HOST \
            -e BASELINR_STORAGE__CONNECTION__PORT=5432 \
            $DOCKER_IMAGE_NAME \
            baselinr status \
              --config $BASELINR_CONFIG_PATH \
              --json \
              --limit 5

          # Test drift-only mode
          docker run --rm \
            --network $DOCKER_NETWORK_NAME \
            -e BASELINR_SOURCE__HOST=$BASELINR_DB_HOST \
            -e BASELINR_SOURCE__PORT=5432 \
            -e BASELINR_STORAGE__CONNECTION__HOST=$BASELINR_DB_HOST \
            -e BASELINR_STORAGE__CONNECTION__PORT=5432 \
            $DOCKER_IMAGE_NAME \
            baselinr status \
              --config $BASELINR_CONFIG_PATH \
              --drift-only

      - name: Dump PostgreSQL logs on failure
        if: failure()
        run: docker logs baselinr_postgres || true

      - name: Shutdown Docker services
        if: always()
        run: docker compose -f docker/docker-compose.yml -p $COMPOSE_PROJECT_NAME down -v
