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

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOCK_FILE="${PROD_REPAIR_LOCK_FILE:-/tmp/nexuscrm_prod_repair_daemon.lock}"
STATE_DIR="${PROD_REPAIR_STATE_DIR:-${SCRIPT_DIR}/.prod_repair_state}"
SUMMARY_JSON="${PROD_REPAIR_SUMMARY_JSON:-${STATE_DIR}/latest_summary.json}"
SLEEP_SECONDS="${PROD_REPAIR_SLEEP_SECONDS:-300}"
MAX_CYCLES="${PROD_REPAIR_MAX_CYCLES:-0}"
PYTHON_BIN="${PYTHON_BIN:-python3}"
ACTIVE_LOAD_PATTERN="${PROD_REPAIR_ACTIVE_LOAD_PATTERN:-python3 .*load_salesforce_snapshot_to_tidb.py}"
MAX_WORKERS="${PROD_REPAIR_MAX_WORKERS:-1}"

mkdir -p "${STATE_DIR}"

exec 9>"${LOCK_FILE}"
if ! flock -n 9; then
  echo "[prod-repair-daemon] another instance already holds ${LOCK_FILE}" >&2
  exit 1
fi

cycle=0
while true; do
  cycle=$((cycle + 1))
  echo "[prod-repair-daemon] cycle=${cycle} started_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
  if pgrep -af "${ACTIVE_LOAD_PATTERN}" >/dev/null 2>&1; then
    echo "[prod-repair-daemon] active loader detected; sleeping ${SLEEP_SECONDS}s"
    sleep "${SLEEP_SECONDS}"
    continue
  fi
  set +e
  repair_entrypoint="${SCRIPT_DIR}/run_prod_repair_cycle.py"
  repair_args=(
    --readonly-config "${SF_READONLY_CONFIG_PATH:?missing SF_READONLY_CONFIG_PATH}"
    --snapshot-root "${PROD_REPAIR_SNAPSHOT_ROOT:?missing PROD_REPAIR_SNAPSHOT_ROOT}"
    --output-root "${PROD_REPAIR_OUTPUT_ROOT:-${PROD_REPAIR_SNAPSHOT_ROOT}}"
    --db-host "${TIDB_PROD_HOST:?missing TIDB_PROD_HOST}"
    --db-port "${TIDB_PROD_PORT:-4000}"
    --db-user "${TIDB_PROD_USER:?missing TIDB_PROD_USER}"
    --db-password "${TIDB_PROD_PASSWORD:?missing TIDB_PROD_PASSWORD}"
    --db-database "${TIDB_PROD_DATABASE:?missing TIDB_PROD_DATABASE}"
    --state-dir "${STATE_DIR}"
    --summary-json "${SUMMARY_JSON}"
  )
  if [[ "${MAX_WORKERS}" != "1" ]]; then
    repair_entrypoint="${SCRIPT_DIR}/run_prod_parallel_repair.py"
    repair_args+=(--max-workers "${MAX_WORKERS}")
  fi
  "${PYTHON_BIN}" "${repair_entrypoint}" "${repair_args[@]}"
  exit_code=$?
  set -e
  echo "[prod-repair-daemon] cycle=${cycle} exit_code=${exit_code} finished_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)"

  if [[ "${MAX_CYCLES}" != "0" && "${cycle}" -ge "${MAX_CYCLES}" ]]; then
    break
  fi
  sleep "${SLEEP_SECONDS}"
done
