#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
BACKEND_DIR="$PROJECT_DIR/backend"
TESTS_DIR="$PROJECT_DIR/tests/e2e-api"

PYTHON="${PYTHON:-$(command -v python3 || command -v python || true)}"
GO_BIN="${GO_BIN:-$(command -v go || true)}"

if [ -z "${PYTHON}" ] || [ ! -x "${PYTHON}" ]; then
    echo "❌ Python not found"
    exit 1
fi

if [ -z "${GO_BIN}" ] || [ ! -x "${GO_BIN}" ]; then
    echo "❌ Go not found"
    exit 1
fi

TIDB_HOST="${TIDB_HOST:-${DB_HOST:-}}"
TIDB_PORT="${TIDB_PORT:-${DB_PORT:-4000}}"
TIDB_USER="${TIDB_USER:-${DB_USERNAME:-}}"
TIDB_PASSWORD="${TIDB_PASSWORD:-${DB_PASSWORD:-}}"
TIDB_DATABASE="${TIDB_DATABASE:-${DB_DATABASE:-nexuscrm}}"

PORT="${PORT:-43001}"
NEXUSCRM_URL="${NEXUSCRM_URL:-http://127.0.0.1:${PORT}}"
NEXUSCRM_USERNAME="${NEXUSCRM_USERNAME:-admin@test.com}"
NEXUSCRM_PASSWORD="${NEXUSCRM_PASSWORD:-${NEXUS_ADMIN_PASSWORD:-}}"

E2E_API_SCENES="${E2E_API_SCENES:-demo,validation,contract,quote_line}"
E2E_API_SKIP_SETUP="${E2E_API_SKIP_SETUP:-1}"
E2E_API_BUILD_BACKEND="${E2E_API_BUILD_BACKEND:-1}"
E2E_API_START_BACKEND="${E2E_API_START_BACKEND:-1}"
E2E_API_PREPARE_DB="${E2E_API_PREPARE_DB:-0}"
E2E_API_FAIL_ON_FAILURE="${E2E_API_FAIL_ON_FAILURE:-0}"
E2E_API_PARALLEL="${E2E_API_PARALLEL:-1}"
E2E_API_WAIT_SECONDS="${E2E_API_WAIT_SECONDS:-60}"
E2E_API_RUN_TIMEOUT_SECONDS="${E2E_API_RUN_TIMEOUT_SECONDS:-0}"
SKIP_BOOTSTRAP="${SKIP_BOOTSTRAP:-true}"
E2E_API_LOG_PATH="${E2E_API_LOG_PATH:-/tmp/nexuscrm-e2e-api.log}"

if [ -z "${TIDB_HOST}" ] || [ -z "${TIDB_USER}" ]; then
    echo "❌ Missing database connection. Set TIDB_* or DB_* environment variables."
    exit 1
fi

if [ -z "${NEXUSCRM_PASSWORD}" ]; then
    echo "❌ Missing NEXUSCRM_PASSWORD or NEXUS_ADMIN_PASSWORD."
    exit 1
fi

export TIDB_HOST TIDB_PORT TIDB_USER TIDB_PASSWORD TIDB_DATABASE
export DB_HOST="${DB_HOST:-$TIDB_HOST}"
export DB_PORT="${DB_PORT:-$TIDB_PORT}"
export DB_USERNAME="${DB_USERNAME:-$TIDB_USER}"
export DB_PASSWORD="${DB_PASSWORD:-$TIDB_PASSWORD}"
export DB_DATABASE="${DB_DATABASE:-$TIDB_DATABASE}"

BACKEND_PID=""
cleanup() {
    if [ -n "${BACKEND_PID}" ] && kill -0 "${BACKEND_PID}" >/dev/null 2>&1; then
        kill "${BACKEND_PID}" >/dev/null 2>&1 || true
        wait "${BACKEND_PID}" >/dev/null 2>&1 || true
    fi
}
trap cleanup EXIT

if [ "${E2E_API_PREPARE_DB}" = "1" ]; then
    echo "📦 Applying backend metadata to ${TIDB_HOST}:${TIDB_PORT}/${TIDB_DATABASE}..."
    (
        cd "${BACKEND_DIR}"
        TIDB_HOST="${TIDB_HOST}" \
        TIDB_PORT="${TIDB_PORT}" \
        TIDB_USER="${TIDB_USER}" \
        TIDB_PASSWORD="${TIDB_PASSWORD}" \
        TIDB_DATABASE="${TIDB_DATABASE}" \
        NEXUS_ADMIN_PASSWORD="${NEXUSCRM_PASSWORD}" \
        "${GO_BIN}" run ./cmd/setup apply
    )

    # Default scene set includes tenant-only cases (e.g.
    # lead_status_timestamp → SDR-001/002/008) whose runtime
    # artefacts — tenant Flow + picklist tag merge — only land
    # in the DB via apply-tenant. Keep the local prepare path
    # self-consistent with the scene list so developers running
    # the default runner on a fresh DB don't see spurious reds.
    # Operators who explicitly want a greenfield (no tenant
    # overlay) run can set E2E_API_SKIP_TENANT=1.
    if [ "${E2E_API_SKIP_TENANT:-0}" != "1" ]; then
        echo "📦 Applying tenant overlay (PingCAP)..."
        (
            cd "${BACKEND_DIR}"
            TIDB_HOST="${TIDB_HOST}" \
            TIDB_PORT="${TIDB_PORT}" \
            TIDB_USER="${TIDB_USER}" \
            TIDB_PASSWORD="${TIDB_PASSWORD}" \
            TIDB_DATABASE="${TIDB_DATABASE}" \
            NEXUSCRM_APPLY_TENANT_OVERLAY=1 \
            NEXUSCRM_TENANT_OVERLAY_DIR=internal/controlplane/tenants/pingcap \
            AUTONUMBER_SEED_TOLERATE_LEGACY=true \
            "${GO_BIN}" run ./cmd/setup apply-tenant
        )
    fi
fi

if [ "${E2E_API_BUILD_BACKEND}" = "1" ]; then
    if [ -x /tmp/nexuscrm-server ] && [ -f /tmp/nexuscrm-server ]; then
        echo "✅ Backend binary already exists, skipping build"
    else
        echo "🔨 Building backend..."
        (
            cd "${BACKEND_DIR}"
            "${GO_BIN}" build -o /tmp/nexuscrm-server ./cmd/server/
        )
    fi
fi

if [ "${E2E_API_START_BACKEND}" = "1" ]; then
    echo "🚀 Starting backend on ${NEXUSCRM_URL}..."
    rm -f "${E2E_API_LOG_PATH}"
    (
        cd "${BACKEND_DIR}"
        TIDB_HOST="${TIDB_HOST}" \
        TIDB_PORT="${TIDB_PORT}" \
        TIDB_USER="${TIDB_USER}" \
        TIDB_PASSWORD="${TIDB_PASSWORD}" \
        TIDB_DATABASE="${TIDB_DATABASE}" \
        PORT="${PORT}" \
        SKIP_BOOTSTRAP="${SKIP_BOOTSTRAP}" \
        /tmp/nexuscrm-server
    ) > "${E2E_API_LOG_PATH}" 2>&1 &
    BACKEND_PID=$!

    for i in $(seq 1 "${E2E_API_WAIT_SECONDS}"); do
        if curl -sS "${NEXUSCRM_URL}/health" >/dev/null 2>&1; then
            echo "✅ Backend started"
            break
        fi

        if [ "${i}" = "${E2E_API_WAIT_SECONDS}" ]; then
            echo "❌ Backend failed to start"
            cat "${E2E_API_LOG_PATH}"
            exit 1
        fi
        sleep 1
    done
fi

RUNNER_ARGS=()
if [ -n "${E2E_API_SCENES}" ] && [ "${E2E_API_SCENES}" != "all" ]; then
    RUNNER_ARGS+=(--scene "${E2E_API_SCENES}")
fi
if [ "${E2E_API_SKIP_SETUP}" = "1" ]; then
    RUNNER_ARGS+=(--skip-setup)
fi
if [ "${E2E_API_FAIL_ON_FAILURE}" = "1" ]; then
    RUNNER_ARGS+=(--fail-on-failures)
fi
if [ -n "${E2E_API_PARALLEL}" ] && [ "${E2E_API_PARALLEL}" != "1" ]; then
    RUNNER_ARGS+=(--parallel "${E2E_API_PARALLEL}")
fi

echo "🧪 Running E2E API tests..."
echo "   Scenes: ${E2E_API_SCENES}"
echo "   Skip seed setup: ${E2E_API_SKIP_SETUP}"
echo "   Parallel workers: ${E2E_API_PARALLEL}"
echo "   Fail on failures: ${E2E_API_FAIL_ON_FAILURE}"
if [ "${E2E_API_RUN_TIMEOUT_SECONDS}" != "0" ]; then
    echo "   Hard timeout: ${E2E_API_RUN_TIMEOUT_SECONDS}s"
fi
echo "   Backend log: ${E2E_API_LOG_PATH}"

RUNNER_CMD=("${PYTHON}" runner.py "${RUNNER_ARGS[@]}")

set +e
(
    cd "${TESTS_DIR}"
    if [ "${E2E_API_RUN_TIMEOUT_SECONDS}" != "0" ] && command -v timeout >/dev/null 2>&1; then
        NEXUSCRM_URL="${NEXUSCRM_URL}" \
        NEXUSCRM_USERNAME="${NEXUSCRM_USERNAME}" \
        NEXUSCRM_PASSWORD="${NEXUSCRM_PASSWORD}" \
        TIDB_HOST="${TIDB_HOST}" \
        TIDB_PORT="${TIDB_PORT}" \
        TIDB_USER="${TIDB_USER}" \
        TIDB_PASSWORD="${TIDB_PASSWORD}" \
        TIDB_DATABASE="${TIDB_DATABASE}" \
        timeout --foreground --signal=TERM --kill-after=30s "${E2E_API_RUN_TIMEOUT_SECONDS}s" "${RUNNER_CMD[@]}"
    else
        if [ "${E2E_API_RUN_TIMEOUT_SECONDS}" != "0" ]; then
            echo "⚠️ timeout command not found; running without hard timeout guard"
        fi
        NEXUSCRM_URL="${NEXUSCRM_URL}" \
        NEXUSCRM_USERNAME="${NEXUSCRM_USERNAME}" \
        NEXUSCRM_PASSWORD="${NEXUSCRM_PASSWORD}" \
        TIDB_HOST="${TIDB_HOST}" \
        TIDB_PORT="${TIDB_PORT}" \
        TIDB_USER="${TIDB_USER}" \
        TIDB_PASSWORD="${TIDB_PASSWORD}" \
        TIDB_DATABASE="${TIDB_DATABASE}" \
        "${RUNNER_CMD[@]}"
    fi
)
TEST_EXIT_CODE=$?
set -e

if [ "${TEST_EXIT_CODE}" -eq 124 ]; then
    echo "❌ E2E API tests timed out after ${E2E_API_RUN_TIMEOUT_SECONDS}s."
fi

LATEST_REPORT="$(ls -t "${TESTS_DIR}"/report-*.json 2>/dev/null | head -1 || true)"
if [ -n "${LATEST_REPORT}" ]; then
    echo "📊 Latest report: ${LATEST_REPORT}"
    "${PYTHON}" "${TESTS_DIR}/generate_report.py" "${LATEST_REPORT}" || true
fi

# Exit with the test runner's exit code
if [ "${TEST_EXIT_CODE}" -ne 0 ]; then
    echo "❌ E2E API tests failed. See report for details."
    exit "${TEST_EXIT_CODE}"
fi
