#!/usr/bin/env bash
# Pytest Playwright Docker Wrapper
#
# ⚠️ RECOMMENDED WORKFLOW: Always use this script for visual regression testing
# and baseline updates instead of running pytest locally.
#
# Why use this script?
# - ✅ WebKit support: WebKit requires system dependencies not available on Fedora/RHEL
# - ✅ Consistency: Same environment as CI (no "works locally but fails in CI" issues)
# - ✅ Pre-installed browsers: chromium, firefox, and webkit ready to use
# - ✅ No local setup: No need to install Playwright browsers locally
#
# Runs pytest with Playwright tests inside a custom Docker container with all
# browser dependencies pre-installed. This bypasses Fedora compatibility issues
# while maintaining full Playwright functionality.
#
# Usage:
#   ./scripts/pytest-playwright [pytest-args...]
#   ./scripts/pytest-playwright                              # Defaults to qa/web/tests/
#   ./scripts/pytest-playwright qa/web/tests/visual/
#   ./scripts/pytest-playwright qa/web/tests/visual/ --browser firefox
#   ./scripts/pytest-playwright qa/web/tests/visual/ --update-snapshots
#
# Update Visual Regression Baselines (RECOMMENDED):
#   ./scripts/pytest-playwright qa/web/tests/visual/ --update-snapshots --browser chromium --browser firefox --browser webkit
#
# Prerequisites:
#   - Docker installed and running: docker info
#   - Web server running on localhost:5000: nhl-scrabble serve
#
# Environment Variables:
#   PLAYWRIGHT_IMAGE    Docker image to use (default: ghcr.io/bdperkin/nhl-scrabble-playwright:latest)
#   PLAYWRIGHT_NO_PULL  Skip pulling image if set to 'true'
#   WEB_SERVER_URL      Override web server URL (default: http://localhost:5000)

set -euo pipefail

# Configuration
# Use custom GHCR image by default (has Playwright pre-installed)
# Can override with PLAYWRIGHT_IMAGE environment variable for testing
PLAYWRIGHT_IMAGE="${PLAYWRIGHT_IMAGE:-ghcr.io/bdperkin/nhl-scrabble-playwright:latest}"
PLAYWRIGHT_NO_PULL="${PLAYWRIGHT_NO_PULL:-false}"
WEB_SERVER_URL="${WEB_SERVER_URL:-http://localhost:5000}"

# Detect repository root (script is in scripts/ subdirectory)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Print colored message
log() {
    local color="$1"
    shift
    echo -e "${color}[pytest-playwright]${NC} $*"
}

# Check if Docker is available
if ! command -v docker &> /dev/null; then
    log "${RED}" "ERROR: Docker is not installed or not in PATH"
    log "${YELLOW}" "Install Docker: https://docs.docker.com/get-docker/"
    exit 1
fi

# Check if Docker daemon is running
if ! docker info &> /dev/null; then
    log "${RED}" "ERROR: Docker daemon is not running"
    log "${YELLOW}" "Start Docker: sudo systemctl start docker"
    exit 1
fi

# Check if web server is running on localhost:5000
if command -v curl &> /dev/null; then
    if ! curl -s -f -m 2 http://localhost:5000 > /dev/null 2>&1; then
        log "${YELLOW}" "WARNING: Web server not detected on localhost:5000"
        log "${YELLOW}" "Start server: nhl-scrabble serve --host 0.0.0.0 --port 5000"
        log "${YELLOW}" "Tests will fail without a running web server"
    else
        log "${GREEN}" "Web server detected on localhost:5000"
    fi
fi

# Pull Playwright image if needed
if [[ "${PLAYWRIGHT_NO_PULL}" != "true" ]]; then
    if ! docker images "${PLAYWRIGHT_IMAGE}" --format '{{.Repository}}:{{.Tag}}' | grep -q "${PLAYWRIGHT_IMAGE}"; then
        log "${BLUE}" "Pulling Playwright Docker image: ${PLAYWRIGHT_IMAGE}"
        if ! docker pull "${PLAYWRIGHT_IMAGE}"; then
            log "${RED}" "ERROR: Failed to pull Docker image"
            exit 1
        fi
    fi
fi

# Determine working directory relative to repo root
CURRENT_DIR="$(pwd)"
if [[ "${CURRENT_DIR}" == "${REPO_ROOT}"* ]]; then
    # Inside repo, calculate relative path
    REL_PATH="${CURRENT_DIR#${REPO_ROOT}}"
    REL_PATH="${REL_PATH#/}" # Remove leading slash
    WORKDIR="/work/${REL_PATH}"
else
    # Outside repo, use /work as working directory
    WORKDIR="/work"
fi

# Install main package dependencies to user location (avoids /work permission issues)
# All QA test dependencies are pre-installed in the Docker image
# PYTHONPATH already includes /work/src and /work/qa/web, so imports will work
# Note: Running as root in container, so pip warnings about root user are suppressed
INSTALL_CMD="pip install --user -q --no-cache-dir --no-warn-script-location --disable-pip-version-check --root-user-action=ignore certifi click colorlog dicttoxml fastapi httpx jinja2 platformdirs prompt-toolkit pydantic pydantic-settings pyyaml requests requests-cache rich starlette unidecode uvicorn"

# Build Docker run command
# Use :z flag for SELinux systems to allow container write access
# Run as root to avoid Firefox permission issues and file ownership conflicts
# Note: Files created in /work will be owned by root, but this is acceptable for CI/test scenarios
DOCKER_CMD=(
    docker run
    --rm                                    # Remove container after exit
    --interactive                           # Keep STDIN open
    --user root                             # Run as root for file permissions
    --network host                          # Access host network (for localhost:5000)
    --volume "${REPO_ROOT}:/work:z"        # Mount repository (with SELinux label)
    --shm-size=2gb                          # Increase shared memory for Firefox
    --workdir "${WORKDIR}"                 # Set working directory
    --env "HOME=/root"                     # Set HOME to /root (required for Firefox when running as root)
    --env "PLAYWRIGHT_BROWSERS_PATH=/home/pwuser/.cache/ms-playwright"  # Browser cache (in image)
    --env "BASE_URL=${WEB_SERVER_URL}"     # Override base URL for tests
    --env "PYTHONUNBUFFERED=1"             # Unbuffered Python output
    --env "PYTHONPATH=/work/src:/work/qa/web"  # Add project sources to Python path
)

# Add TTY flag only if running in a terminal
if [[ -t 1 ]]; then
    DOCKER_CMD+=(--tty)
fi

# Add environment variables from host
declare -a PYTEST_ENVS=(
    "DEBUG"
    "PWDEBUG"
    "CI"
    "PYTEST_CURRENT_TEST"
)

for env_var in "${PYTEST_ENVS[@]}"; do
    if [[ -n "${!env_var:-}" ]]; then
        DOCKER_CMD+=(--env "${env_var}=${!env_var}")
    fi
done

# Check if --update-snapshots is in arguments and if test path is provided
UPDATE_SNAPSHOTS=false
HAS_TEST_PATH=false

for arg in "$@"; do
    if [[ "${arg}" == "--update-snapshots" ]]; then
        UPDATE_SNAPSHOTS=true
    elif [[ ! "${arg}" =~ ^- ]]; then
        # Argument doesn't start with -, so it's a test path
        HAS_TEST_PATH=true
    fi
done

if [[ "${UPDATE_SNAPSHOTS}" == "true" ]]; then
    log "${YELLOW}" "Running with --update-snapshots: Baselines will be regenerated"
fi

# Default to qa/web/tests/ if no test path provided
PYTEST_ARGS=("$@")
if [[ "${HAS_TEST_PATH}" == "false" ]]; then
    PYTEST_ARGS=("qa/web/tests/" "$@")
    log "${BLUE}" "No test path specified, defaulting to qa/web/tests/"
fi

# Disable pytest cache to avoid permission warnings when running in Docker
# The cache plugin tries to write to .pytest_cache which has permission issues
# when the container user doesn't match the host user
PYTEST_CACHE_FLAG="-p no:cacheprovider"

# Execute pytest command in container
log "${GREEN}" "Running: pytest ${PYTEST_CACHE_FLAG} ${PYTEST_ARGS[*]}"
log "${BLUE}" "Image: ${PLAYWRIGHT_IMAGE}"
log "${BLUE}" "Working directory: ${WORKDIR}"
log "${BLUE}" "Web server URL: ${WEB_SERVER_URL}"

# Run the command with bash to allow setup
# All dependencies are pre-installed in the Docker image
"${DOCKER_CMD[@]}" \
    "${PLAYWRIGHT_IMAGE}" \
    bash -c "${INSTALL_CMD} && pytest ${PYTEST_CACHE_FLAG} ${PYTEST_ARGS[*]}"

EXIT_CODE=$?

if [[ ${EXIT_CODE} -eq 0 ]]; then
    log "${GREEN}" "Tests completed successfully"
else
    log "${RED}" "Tests failed with exit code ${EXIT_CODE}"
fi

exit ${EXIT_CODE}
