#!/bin/sh
set -eu

usage() {
    echo "usage: $0 [env-file]" >&2
    exit 64
}

[ "$#" -le 1 ] || usage

script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
workspace_root=$(CDPATH= cd -- "$script_dir/.." && pwd)
env_file=${1:-"$workspace_root/.env.ci"}

if [ ! -f "$env_file" ]; then
    echo "missing integration environment file: $env_file" >&2
    exit 66
fi
env_file=$(CDPATH= cd -- "$(dirname -- "$env_file")" && pwd)/$(basename -- "$env_file")

# .env.ci is generated by the sam_rebuild development Compose helper and is a
# shell-compatible, credential-bearing local file. Never print its contents.
set -a
# shellcheck disable=SC1090
. "$env_file"
set +a

: "${POSTGRES_HOST:?POSTGRES_HOST is required in $env_file}"
: "${POSTGRES_PORT:?POSTGRES_PORT is required in $env_file}"
: "${POSTGRES_DB:?POSTGRES_DB is required in $env_file}"
: "${POSTGRES_USER:?POSTGRES_USER is required in $env_file}"
: "${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required in $env_file}"
: "${REDIS_URL:?REDIS_URL is required in $env_file}"

integration_schema=${CONDITIONAL_INTEGRATION_SCHEMA:-conditional_integration}
scenario_schema=${SCENARIO_SEED_INTEGRATION_SCHEMA:-conditional_scenario_seed}

for schema in "$integration_schema" "$scenario_schema"; do
    case "$schema" in
        ''|[!a-z_]*|*[!a-z0-9_]*)
            echo "integration schema must be a lowercase PostgreSQL identifier: $schema" >&2
            exit 64
            ;;
    esac
done

build_database_url() {
    SCHEMA_NAME=$1 node --input-type=module -e '
        const required = [
            "POSTGRES_HOST",
            "POSTGRES_PORT",
            "POSTGRES_DB",
            "POSTGRES_USER",
            "POSTGRES_PASSWORD",
            "SCHEMA_NAME",
        ];
        for (const name of required) {
            if (!process.env[name]) {
                throw new Error(`missing ${name}`);
            }
        }
        const url = new URL("postgresql://localhost");
        url.hostname = process.env.POSTGRES_HOST;
        url.port = process.env.POSTGRES_PORT;
        url.username = process.env.POSTGRES_USER;
        url.password = process.env.POSTGRES_PASSWORD;
        url.pathname = `/${process.env.POSTGRES_DB}`;
        url.searchParams.set("schema", process.env.SCHEMA_NAME);
        process.stdout.write(url.href);
    '
}

run_marked_tests() {
    package_dir=$1
    marker=$2
    label=$3
    test_files=$(cd "$workspace_root/$package_dir" && rg -l "$marker" test -g '*.test.ts' | sort)
    if [ -z "$test_files" ]; then
        echo "no $label tests found under $package_dir" >&2
        exit 65
    fi
    echo "running $label tests in $package_dir"
    (
        cd "$workspace_root/$package_dir"
        printf '%s\n' "$test_files" |
            xargs -r pnpm exec vitest run --no-file-parallelism --maxWorkers=1
    )
}

cd "$workspace_root"
pnpm install --frozen-lockfile
pnpm --filter @sammo-ts/infra prisma:generate
pnpm --filter @sammo-ts/common build

database_url=$(build_database_url "$integration_schema")
export POSTGRES_SCHEMA=$integration_schema
export DATABASE_URL=$database_url
export INPUT_EVENT_DATABASE_URL=$database_url
export GENERAL_LIFECYCLE_DATABASE_URL=$database_url
export TURN_DAEMON_LEASE_DATABASE_URL=$database_url
export TURN_DIFFERENTIAL_DATABASE_URL=$database_url

pnpm --filter @sammo-ts/infra prisma:db:push:game

database_markers='INPUT_EVENT_DATABASE_URL|GENERAL_LIFECYCLE_DATABASE_URL|TURN_DAEMON_LEASE_DATABASE_URL'
run_marked_tests app/game-api "$database_markers" "PostgreSQL"
run_marked_tests app/game-engine "$database_markers" "PostgreSQL"
run_marked_tests tools/integration-tests \
    'TURN_DIFFERENTIAL_DATABASE_URL|INPUT_EVENT_DATABASE_URL' \
    "PostgreSQL snapshot"
run_marked_tests app/game-api 'process\.env\.REDIS_URL' "Redis"

scenario_database_url=$(build_database_url "$scenario_schema")
(
    export POSTGRES_SCHEMA=$scenario_schema
    export DATABASE_URL=$scenario_database_url
    pnpm --filter @sammo-ts/infra prisma:db:push:game
    cd "$workspace_root/app/game-engine"
    pnpm exec vitest run --no-file-parallelism --maxWorkers=1 test/scenarioSeeder.test.ts
)

echo "conditional PostgreSQL and Redis integration tests passed"
