#!/usr/bin/env bash
# scripts/check-fresh-clone -- smoke check that mirrors a clean install path.
#
# Verifies that:
#   1. The frontend builds end-to-end.
#   2. The frontend test suite (vitest) passes.
#   3. The Python test suite passes.
#   4. The server boots and /api/stats responds within budget.
#
# Run this before tagging a release or after big refactors to catch
# obvious regressions. Used by CI (.github/workflows/ci.yml) as the single
# source of truth for the fresh-clone smoke gate.
#
# Lifecycle:
#   - If data/claude.db doesn't exist, an empty-schema DB is created so the
#     server has something to open. /api/stats returns zero-valued counts on
#     empty corpora (see tests/test_routes_smoke.py::test_stats_empty_db_returns_zeroes).
#   - If the server isn't already running on :8000, this script starts it via
#     `uv run scripts/serve start` and stops it again on exit. If the server
#     was already running (e.g. you have `serve start` going in another shell),
#     it's left alone.
#
# Env:
#   PERF_HOST    Override host:port for the probe (default 127.0.0.1:8000).
#   STATS_BUDGET_MS  Max acceptable /api/stats response time in ms (default 2000).

set -euo pipefail

# Project root is one level up from this script (regardless of cwd).
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
HOST="${PERF_HOST:-127.0.0.1:8000}"
STATS_BUDGET_MS="${STATS_BUDGET_MS:-2000}"

# Track whether we started the server, so we only stop what we started.
WE_STARTED_SERVER=0

cleanup() {
  if [ "$WE_STARTED_SERVER" = "1" ]; then
    echo "Stopping server (we started it)..."
    ( cd "$ROOT" && uv run scripts/serve stop ) || true
  fi
}
trap cleanup EXIT

echo "Verifying frontend can build..."
( cd "$ROOT/frontend" && npm run build >/dev/null )
echo "  frontend build ok"

echo "Verifying frontend tests pass (vitest)..."
( cd "$ROOT/frontend" && npm run test )
echo "  vitest ok"

echo "Verifying tests pass..."
( cd "$ROOT" && uv run pytest tests/ )
echo "  pytest ok"

# Ensure a DB exists so the server can open it. We don't overwrite an
# existing DB -- on a dev machine the real claude.db is what you want to
# probe against; on a fresh clone we create an empty schema.
if [ ! -f "$ROOT/data/claude.db" ]; then
  echo "No data/claude.db found, creating empty schema..."
  mkdir -p "$ROOT/data"
  ( cd "$ROOT" && uv run python -c "
import sqlite3
from pathlib import Path
from claude_timeline.build.schema import setup_schema
db = Path('data/claude.db')
conn = sqlite3.connect(str(db))
try:
    setup_schema(conn)
finally:
    conn.close()
print(f'  Created empty schema at {db}')
" )
fi

# Ensure server is running. If it's already up (dev machine workflow), leave
# it alone; otherwise start it ourselves and remember to stop it on exit.
echo "Ensuring server is running..."
if curl -fsS --max-time 2 "http://${HOST}/api/stats" >/dev/null 2>&1; then
  echo "  server already running, reusing"
else
  echo "  starting server in background..."
  ( cd "$ROOT" && uv run scripts/serve start )
  WE_STARTED_SERVER=1
  # Poll up to 30s for the server to become reachable. CI runners are slower
  # than a dev box; the model-load path can take ~10s on first import.
  for i in $(seq 1 30); do
    if curl -fsS --max-time 2 "http://${HOST}/api/stats" >/dev/null 2>&1; then
      echo "  server ready after ${i}s"
      break
    fi
    if [ "$i" = "30" ]; then
      echo "  server did not become ready within 30s" >&2
      cat "$ROOT/data/server.log" >&2 || true
      exit 1
    fi
    sleep 1
  done
fi

# Real probe: time the response and assert it's under the budget. Matches
# scripts/perf-check's stats budget, with slack for slower CI runners.
elapsed_ms=$(curl -fsS -o /dev/null -w '%{time_total}\n' \
  --max-time 5 "http://${HOST}/api/stats" \
  | awk '{printf "%d", $1 * 1000}')
echo "  /api/stats responded in ${elapsed_ms}ms (budget: ${STATS_BUDGET_MS}ms)"
if [ "$elapsed_ms" -gt "$STATS_BUDGET_MS" ]; then
  echo "FAIL: /api/stats took ${elapsed_ms}ms (budget: ${STATS_BUDGET_MS}ms)" >&2
  exit 1
fi

echo "ok"
