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

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROM_E2E_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
REPO_ROOT="$(git -C "${PROM_E2E_ROOT}" rev-parse --show-toplevel)"
LOCAL_E2E_ROOT="${REPO_ROOT}/pipeline/tools/local-e2e"

PROM_E2E_ENV_FILE="${PROM_E2E_ENV_FILE:-${LOCAL_E2E_ROOT}/env/test.env}"
if [[ ! -f "${PROM_E2E_ENV_FILE}" ]]; then
  echo "❌ prom-e2e env file not found: ${PROM_E2E_ENV_FILE}"
  exit 1
fi
source "${PROM_E2E_ENV_FILE}"

GENERATED_DIR="${PROM_E2E_ROOT}/generated"
GENERATED_BIN_DIR="${GENERATED_DIR}/bin"
GENERATED_CONFIG_DIR="${GENERATED_DIR}/configs"
GENERATED_COMPOSE_DIR="${GENERATED_DIR}/compose"
GENERATED_RUN_DIR="${GENERATED_DIR}/run"
GENERATED_RESULTS_DIR="${GENERATED_DIR}/results"
MIRRORD_GLOBAL_PID_FILE="${GENERATED_RUN_DIR}/mirrord-global.pid"
MIRRORD_REGIONAL_PID_FILE="${GENERATED_RUN_DIR}/mirrord-regional.pid"
MIRRORD_DEDICATED_PID_FILE="${GENERATED_RUN_DIR}/mirrord-dedicated.pid"

PROM_E2E_PROMETHEUS_PORT="${PROM_E2E_PROMETHEUS_PORT:-19090}"
PROM_E2E_GRAFANA_PORT="${PROM_E2E_GRAFANA_PORT:-13000}"
PROM_E2E_GATEWAY="${PROM_E2E_GATEWAY:-172.29.240.1}"
DEDICATED_EXPORTER_PORT="${DEDICATED_EXPORTER_PORT:-18184}"
PREMIUM_EXPORTER_PORT="${PREMIUM_EXPORTER_PORT:-18181}"
ESSENTIAL_EXPORTER_PORT="${ESSENTIAL_EXPORTER_PORT:-18182}"
STARTER_EXPORTER_PORT="${STARTER_EXPORTER_PORT:-18183}"
PROM_E2E_ROUND_NAME="${PROM_E2E_ROUND_NAME:-$(date +%Y%m%d-%H%M%S)}"
PROM_E2E_RESULT_DIR="${GENERATED_RESULTS_DIR}/${PROM_E2E_ROUND_NAME}"

mkdir -p \
  "${GENERATED_BIN_DIR}" \
  "${GENERATED_CONFIG_DIR}" \
  "${GENERATED_COMPOSE_DIR}/prometheus-data" \
  "${GENERATED_RUN_DIR}" \
  "${PROM_E2E_RESULT_DIR}"

PROM_BIN="${GENERATED_BIN_DIR}/prometheus-feature"

require_cluster_id() {
  local cluster_id="$1"
  local name="$2"
  if [[ -z "${cluster_id}" ]]; then
    echo "❌ ${name} cluster id is empty"
    exit 1
  fi
}

require_cluster_id "${CLUSTER_ID_DEDICATED:-}" "Dedicated"
require_cluster_id "${CLUSTER_ID_PREMIUM:-}" "Premium"
require_cluster_id "${CLUSTER_ID_ESSENTIAL:-}" "Essential"
require_cluster_id "${CLUSTER_ID_STARTER:-}" "Starter"

wait_http() {
  local url="$1"
  local attempts="${2:-30}"
  local i
  for i in $(seq 1 "${attempts}"); do
    if curl -sf "${url}" > /dev/null 2>&1; then
      return 0
    fi
    sleep 1
  done
  return 1
}

wait_tcp() {
  local host="$1"
  local port="$2"
  local attempts="${3:-30}"
  local i
  for i in $(seq 1 "${attempts}"); do
    if nc -z "${host}" "${port}" >/dev/null 2>&1; then
      return 0
    fi
    sleep 1
  done
  return 1
}

build_prometheus_binary() {
  echo "[prom-e2e] building local prometheus binary..."
  (
    cd "${REPO_ROOT}/pipeline"
    CGO_ENABLED=0 go build -o "${PROM_BIN}" cmd/prometheus/main.go
  )
}

generate_local_e2e_configs() {
  echo "[prom-e2e] generating TiDB-X configs via local-e2e..."
  LOCAL_VERIFICATION_ENV_FILE="${PROM_E2E_ENV_FILE}" \
    bash "${LOCAL_E2E_ROOT}/scripts/gen-configs.sh" > /dev/null

  cp \
    "${LOCAL_E2E_ROOT}/generated/configs/prometheus-config-Dedicated-${CLUSTER_ID_DEDICATED}.yaml" \
    "${LOCAL_E2E_ROOT}/generated/configs/prometheus-config-Premium-${CLUSTER_ID_PREMIUM}.yaml" \
    "${LOCAL_E2E_ROOT}/generated/configs/prometheus-config-Essential-${CLUSTER_ID_ESSENTIAL}.yaml" \
    "${LOCAL_E2E_ROOT}/generated/configs/prometheus-config-Starter-${CLUSTER_ID_STARTER}.yaml" \
    "${GENERATED_CONFIG_DIR}/"
}

render_exporter_config() {
  local service_plan="$1"
  local cluster_id="$2"
  local port="$3"
  local source_config="${GENERATED_CONFIG_DIR}/prometheus-config-${service_plan}-${cluster_id}.yaml"
  local target_name="${4:-${service_plan,,}}"
  local target_config="${GENERATED_CONFIG_DIR}/runtime-prometheus-config-${target_name}.yaml"

  sed \
    -e "s/0\\.0\\.0\\.0:8080/0.0.0.0:${port}/" \
    -e "s/grpcPort: 10001/grpcPort: $(( 10001 + port - 18180 ))/" \
    -e "s/metricsPort: 9091/metricsPort: $(( 9091 + port - 18180 ))/" \
    "${source_config}" > "${target_config}"

  echo "${target_config}"
}

render_runtime_configs() {
  render_exporter_config "Dedicated" "${CLUSTER_ID_DEDICATED}" "${DEDICATED_EXPORTER_PORT}" "dedicated" >/dev/null
  render_exporter_config "Premium" "${CLUSTER_ID_PREMIUM}" "${PREMIUM_EXPORTER_PORT}" "premium" >/dev/null
  render_exporter_config "Essential" "${CLUSTER_ID_ESSENTIAL}" "${ESSENTIAL_EXPORTER_PORT}" "essential" >/dev/null
  render_exporter_config "Starter" "${CLUSTER_ID_STARTER}" "${STARTER_EXPORTER_PORT}" "starter" >/dev/null
}

render_prometheus_config() {
  cat > "${GENERATED_COMPOSE_DIR}/prometheus.yml" <<EOF
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: dedicated
    metrics_path: /public_api/v1/clusters/${CLUSTER_ID_DEDICATED}/metrics
    authorization:
      credentials: ${PROMETHEUS_TOKEN}
    static_configs:
      - targets: ['127.0.0.1:${DEDICATED_EXPORTER_PORT}']

  - job_name: premium
    metrics_path: /public_api/v1/clusters/${CLUSTER_ID_PREMIUM}/metrics
    authorization:
      credentials: ${PROMETHEUS_TOKEN}
    static_configs:
      - targets: ['127.0.0.1:${PREMIUM_EXPORTER_PORT}']

  - job_name: essential
    metrics_path: /public_api/v1/clusters/${CLUSTER_ID_ESSENTIAL}/metrics
    authorization:
      credentials: ${PROMETHEUS_TOKEN}
    static_configs:
      - targets: ['127.0.0.1:${ESSENTIAL_EXPORTER_PORT}']

  - job_name: starter
    metrics_path: /public_api/v1/clusters/${CLUSTER_ID_STARTER}/metrics
    authorization:
      credentials: ${PROMETHEUS_TOKEN}
    static_configs:
      - targets: ['127.0.0.1:${STARTER_EXPORTER_PORT}']
EOF
}

compose() {
  (
    cd "${PROM_E2E_ROOT}"
    PROM_E2E_PROMETHEUS_PORT="${PROM_E2E_PROMETHEUS_PORT}" \
    PROM_E2E_GRAFANA_PORT="${PROM_E2E_GRAFANA_PORT}" \
    DEDICATED_EXPORTER_PORT="${DEDICATED_EXPORTER_PORT}" \
    PREMIUM_EXPORTER_PORT="${PREMIUM_EXPORTER_PORT}" \
    ESSENTIAL_EXPORTER_PORT="${ESSENTIAL_EXPORTER_PORT}" \
    STARTER_EXPORTER_PORT="${STARTER_EXPORTER_PORT}" \
      docker-compose "$@"
  )
}

start_mirrord_tunnels() {
  if wait_tcp 127.0.0.1 29080 1 && wait_tcp 127.0.0.1 29482 1 && wait_tcp 127.0.0.1 29483 1 && wait_tcp 127.0.0.1 29484 1; then
    echo "[prom-e2e] reusing existing mirrord tunnels"
    return 0
  fi

  if ! wait_tcp 127.0.0.1 29080 1; then
    echo "[prom-e2e] starting mirrord global tunnel..."
    MIRRORD_CHECK_VERSION=false mirrord port-forward \
      --config-file "${REPO_ROOT}/global/.mirrord/port-forward.yaml" \
      -L 29080:www.gs.us-west-2.aws.observability.tidbcloud.com:80 \
      > "${GENERATED_RUN_DIR}/mirrord-global.log" 2>&1 &
    echo "$!" > "${MIRRORD_GLOBAL_PID_FILE}"
  fi

  if ! wait_tcp 127.0.0.1 29482 1 || ! wait_tcp 127.0.0.1 29483 1; then
    echo "[prom-e2e] starting mirrord east regional tunnels..."
    MIRRORD_CHECK_VERSION=false mirrord port-forward \
      --config-file "${REPO_ROOT}/global/.mirrord/port-forward.yaml" \
      -L 29482:www.ds.us-east-1-serverless.aws.observability.tidbcloud.com:443 \
      -L 29483:www.ds.us-east-1-premium.aws.observability.tidbcloud.com:443 \
      > "${GENERATED_RUN_DIR}/mirrord-regional.log" 2>&1 &
    echo "$!" > "${MIRRORD_REGIONAL_PID_FILE}"
  fi

  if ! wait_tcp 127.0.0.1 29484 1; then
    echo "[prom-e2e] starting mirrord dedicated regional tunnel..."
    MIRRORD_CHECK_VERSION=false mirrord port-forward \
      --config-file "${REPO_ROOT}/global/.mirrord/port-forward.yaml" \
      -L 29484:www.ds.us-west-2-staging.aws.observability.tidbcloud.com:443 \
      > "${GENERATED_RUN_DIR}/mirrord-dedicated.log" 2>&1 &
    echo "$!" > "${MIRRORD_DEDICATED_PID_FILE}"
  fi

  wait_tcp 127.0.0.1 29080 45 || { echo "❌ mirrord global tunnel failed"; exit 1; }
  wait_tcp 127.0.0.1 29482 45 || { echo "❌ mirrord serverless tunnel failed"; exit 1; }
  wait_tcp 127.0.0.1 29483 45 || { echo "❌ mirrord premium tunnel failed"; exit 1; }
  wait_tcp 127.0.0.1 29484 45 || { echo "❌ mirrord dedicated tunnel failed"; exit 1; }
}

stop_mirrord_tunnels() {
  for pid_file in "${MIRRORD_GLOBAL_PID_FILE}" "${MIRRORD_REGIONAL_PID_FILE}" "${MIRRORD_DEDICATED_PID_FILE}"; do
    [[ -f "${pid_file}" ]] || continue
    pid="$(cat "${pid_file}")"
    kill "${pid}" 2>/dev/null || true
    rm -f "${pid_file}"
  done
}
