#!/usr/bin/env bash
#
# Быстрый runtime gate для issue 17: проверяет, что daily-wave доходит до
# manifest/check, а live-продолжение реально записывает стык backfill/live.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"

COMPOSE_BIN="${COMPOSE_BIN:-docker compose}"
PROFILE="${PROFILE:-daily-wave}"
GEN_HISTORY_DURATION="${GEN_HISTORY_DURATION:-1h}"
WAIT_CLICKHOUSE_SECONDS="${WAIT_CLICKHOUSE_SECONDS:-60}"
WAIT_STG_SECONDS="${WAIT_STG_SECONDS:-5}"
LIVE_SECONDS="${LIVE_SECONDS:-25}"
GEN_LIVE_CHECK_MINUTES="${GEN_LIVE_CHECK_MINUTES:-10}"
WAIT_LIVE_ROWS_SECONDS="${WAIT_LIVE_ROWS_SECONDS:-2}"

cd "${REPO_ROOT}"

launch_env="$(
  PYTHONPATH="${REPO_ROOT}/generator/src" \
  uv run python -m clickstream_generator.launch \
    backfill \
    --profile "${PROFILE}" \
    --duration "${GEN_HISTORY_DURATION}"
)"
eval "${launch_env}"

wait_for_clickhouse() {
  local deadline
  deadline=$((SECONDS + WAIT_CLICKHOUSE_SECONDS))

  until ${COMPOSE_BIN} exec -T clickhouse clickhouse-client \
      --user=default \
      --password=123456 \
      --query "SELECT 1" >/dev/null 2>&1; do
    if (( SECONDS >= deadline )); then
      echo "Ошибка: ClickHouse не ответил за ${WAIT_CLICKHOUSE_SECONDS} сек." >&2
      exit 1
    fi
    sleep 2
  done
}

stg_total_rows() {
  ${COMPOSE_BIN} exec -T clickhouse clickhouse-client \
    --user=default \
    --password=123456 \
    --query "
SELECT
    (SELECT count() FROM stg.browser_raw)
  + (SELECT count() FROM stg.location_raw)
  + (SELECT count() FROM stg.device_raw)
  + (SELECT count() FROM stg.geo_raw)
FORMAT TabSeparated"
}

stg_crossing_visits() {
  ${COMPOSE_BIN} exec -T clickhouse clickhouse-client \
    --user=default \
    --password=123456 \
    --query "
WITH
    parseDateTime64BestEffort('${GEN_MODEL_T_END}', 6, 'UTC') AS t_end,
    t_end + INTERVAL ${GEN_LIVE_CHECK_MINUTES} MINUTE AS t_live_end,
    browser AS (
        SELECT
            JSONExtractString(raw, 'click_id') AS click_id,
            parseDateTime64BestEffortOrNull(
                JSONExtractString(raw, 'event_timestamp'), 6, 'UTC'
            ) AS event_ts
        FROM stg.browser_raw
        WHERE click_id != ''
          AND event_ts >= t_end - INTERVAL 30 MINUTE
          AND event_ts < t_live_end
    )
SELECT count()
FROM
(
    SELECT
        click_id,
        min(event_ts) AS first_ts,
        max(event_ts) AS last_ts
    FROM browser
    GROUP BY click_id
    HAVING first_ts < t_end AND last_ts >= t_end
)
FORMAT TabSeparated"
}

cleanup_live_generator() {
  ${COMPOSE_BIN} stop generator >/dev/null 2>&1 || true
}

stop_live_generator() {
  # docker compose stop возвращается только после фактической остановки контейнера.
  ${COMPOSE_BIN} stop generator
}
trap cleanup_live_generator EXIT

echo "=== Быстрая runtime-проверка startup-history/live seam ==="
echo "GEN_LAUNCH_PROFILE=${GEN_LAUNCH_PROFILE}"
echo "GEN_HISTORY_DURATION=${GEN_HISTORY_DURATION}"
echo "GEN_MODEL_T_END=${GEN_MODEL_T_END}"
echo ""

echo "Шаг 0: очистка volumes ClickHouse/Kafka/state"
${COMPOSE_BIN} --profile live-generator down -v --remove-orphans

echo "Шаг 1: запуск ClickHouse и Kafka"
${COMPOSE_BIN} up -d clickhouse kafka
wait_for_clickhouse

echo "Шаг 2: применение DDL"
bash "${SCRIPT_DIR}/apply_clickhouse_ddl.sh"

echo "Шаг 3: сборка образа генератора"
${COMPOSE_BIN} build generator

echo "Шаг 4: короткий backfill стартовой истории"
${COMPOSE_BIN} run --rm --no-deps \
  -e GEN_RUN_MODE=backfill \
  -e GEN_STATE_RESET=true \
  -e GEN_LAUNCH_PROFILE="${GEN_LAUNCH_PROFILE}" \
  -e GEN_SEED="${GEN_SEED}" \
  -e GEN_MODEL_T0="${GEN_MODEL_T0}" \
  -e GEN_MODEL_T_END="${GEN_MODEL_T_END}" \
  -e GEN_MODEL_TIMEZONE="${GEN_MODEL_TIMEZONE}" \
  -e GEN_MODEL_TIME_SPEED="${GEN_MODEL_TIME_SPEED}" \
  -e GEN_TICK_SECONDS="${GEN_TICK_SECONDS}" \
  -e GEN_LAMBDA_BASE_PER_MIN="${GEN_LAMBDA_BASE_PER_MIN}" \
  -e GEN_JITTER_PCT="${GEN_JITTER_PCT}" \
  -e GEN_MIN_EVENTS_PER_TICK="${GEN_MIN_EVENTS_PER_TICK}" \
  -e GEN_MAX_EVENTS_PER_TICK="${GEN_MAX_EVENTS_PER_TICK}" \
  generator

echo "Шаг 5: первый batch STG -> ODS -> DDS -> DM"
sleep "${WAIT_STG_SECONDS}"
bash "${SCRIPT_DIR}/run_batch.sh"
stg_rows_before_live="$(stg_total_rows)"

echo "Шаг 6: live-продолжение, ждём переходящий визит в STG до ${LIVE_SECONDS} сек."
GEN_RUN_MODE=live \
GEN_STATE_RESET=false \
GEN_LAUNCH_PROFILE="${GEN_LAUNCH_PROFILE}" \
GEN_SEED="${GEN_SEED}" \
GEN_MODEL_T0="${GEN_MODEL_T0}" \
GEN_MODEL_T_END="${GEN_MODEL_T_END}" \
GEN_MODEL_TIMEZONE="${GEN_MODEL_TIMEZONE}" \
GEN_MODEL_TIME_SPEED="${GEN_MODEL_TIME_SPEED}" \
GEN_TICK_SECONDS="${GEN_TICK_SECONDS}" \
GEN_LAMBDA_BASE_PER_MIN="${GEN_LAMBDA_BASE_PER_MIN}" \
GEN_JITTER_PCT="${GEN_JITTER_PCT}" \
GEN_MIN_EVENTS_PER_TICK="${GEN_MIN_EVENTS_PER_TICK}" \
GEN_MAX_EVENTS_PER_TICK="${GEN_MAX_EVENTS_PER_TICK}" \
${COMPOSE_BIN} up -d --build generator
deadline=$((SECONDS + LIVE_SECONDS))
while true; do
  crossing_visits="$(stg_crossing_visits)"
  [[ "${crossing_visits}" =~ ^[0-9]+$ ]] \
    || { echo "Ошибка: не удалось прочитать переходящие визиты из STG." >&2; exit 1; }
  if (( crossing_visits > 0 )); then
    stg_rows_after_live="$(stg_total_rows)"
    echo "live_stg_rows_before=${stg_rows_before_live}"
    echo "live_stg_rows_after=${stg_rows_after_live}"
    echo "live_stg_crossing_visits=${crossing_visits}"
    break
  fi
  if (( SECONDS >= deadline )); then
    echo "Ошибка: live-продолжение не создало переходящий визит в STG за ${LIVE_SECONDS} сек." >&2
    exit 1
  fi
  sleep 1
done
stop_live_generator

echo "Шаг 7: второй batch после live"
sleep "${WAIT_STG_SECONDS}"
bash "${SCRIPT_DIR}/run_batch.sh"

echo "Шаг 8: проверка manifest/profile/live seam без Superset"
PROFILE="${PROFILE}" \
GEN_LAUNCH_PROFILE="${GEN_LAUNCH_PROFILE}" \
GEN_LIVE_CHECK_MINUTES="${GEN_LIVE_CHECK_MINUTES}" \
WAIT_LIVE_ROWS_SECONDS="${WAIT_LIVE_ROWS_SECONDS}" \
CHECK_LIVE_SEAM=1 \
REQUIRE_SUPERSET=0 \
COMPOSE_BIN="${COMPOSE_BIN}" \
bash "${SCRIPT_DIR}/check_generated_analytics.sh"

echo ""
echo "Готово: runtime-проверка startup-history/live seam прошла."
