#!/usr/bin/env bash
# Генерирует alert-rules.yml со ВСЕМИ алертами из index.html и проверяет его
# через promtool check rules из Docker-образа prom/prometheus.
#
# Использование:  ./check-rules.sh
# Другие версии:  PROM_IMAGES="prom/prometheus:v2.53.2" ./check-rules.sh
# Сохранить YAML: KEEP_DIR=./out ./check-rules.sh
# Скрипт скачан отдельно от index.html — страница берётся с SITE_URL (по умолчанию https://nedago.ru/)
set -euo pipefail

DIR="$(cd "$(dirname "$0")" && pwd)"
PROM_IMAGES="${PROM_IMAGES:-prom/prometheus:v2.53.2 prom/prometheus:v3.5.0}"

command -v node >/dev/null || { echo "Нужен Node.js" >&2; exit 2; }
docker info >/dev/null 2>&1 || { echo "Docker недоступен: запустите Docker Desktop / colima" >&2; exit 2; }

if [[ -n "${KEEP_DIR:-}" ]]; then
  OUT="$(mkdir -p "$KEEP_DIR" && cd "$KEEP_DIR" && pwd)"
else
  OUT="$(mktemp -d)"
  trap 'rm -rf "$OUT"' EXIT
fi

# Берём генератор прямо из index.html, чтобы проверять ровно то, что увидит пользователь.
# Если скрипт скачан отдельно от страницы — забираем её с сайта.
HTML="$DIR/index.html"
if [[ ! -f "$HTML" ]]; then
  SITE_URL="${SITE_URL:-https://nedago.ru/}"
  echo "index.html рядом нет — скачиваю $SITE_URL"
  HTML="$OUT/index.html"
  curl -fsSL "$SITE_URL" -o "$HTML" || { echo "Не удалось скачать $SITE_URL" >&2; exit 2; }
fi

node - "$HTML" "$OUT" <<'EOF'
const fs = require('fs');
const vm = require('vm');
const [htmlPath, out] = process.argv.slice(2);
const js = fs.readFileSync(htmlPath, 'utf8').match(/<script>([\s\S]*?)<\/script>/)[1];
const ctx = { module: { exports: {} } };
vm.createContext(ctx);
vm.runInContext(js, ctx);
const { buildYaml, defaultState } = ctx.module.exports;

const variants = {
  'all-default.yml': {},
  // префикс, метки с кавычкой и runbook — проверка экранирования
  'all-settings.yml': { prefix: 'prod', labels: "env=prod, team=dev'ops", runbook: 'https://wiki.example.com/runbooks/' },
};
for (const [file, settings] of Object.entries(variants)) {
  const { yaml, count } = buildYaml(defaultState('all'), settings);
  fs.writeFileSync(`${out}/${file}`, yaml);
  console.log(`${file}: ${count} алертов`);
}
EOF

# Образ скачиваем отдельно и с повторами: сетевая ошибка не должна выглядеть как ошибка в правилах.
pull() {
  docker image inspect "$1" >/dev/null 2>&1 && return 0
  for attempt in 1 2 3; do
    docker pull -q "$1" >/dev/null && return 0
    echo "  не удалось скачать $1 (попытка $attempt/3)" >&2
    sleep $((attempt * 5))
  done
  return 1
}

rc=0
for image in $PROM_IMAGES; do
  echo "== $image"
  if ! pull "$image"; then
    echo "  ПРОПУЩЕНО: образ недоступен (проблема сети/registry, не правил)" >&2
    [[ $rc -eq 0 ]] && rc=2
    continue
  fi
  docker run --rm -v "$OUT":/rules:ro --entrypoint promtool "$image" \
    check rules /rules/all-default.yml /rules/all-settings.yml || rc=1
done

case $rc in
  0) echo "OK: все правила валидны" ;;
  1) echo "ОШИБКИ В ПРАВИЛАХ: см. вывод promtool выше" >&2 ;;
  2) echo "ПРОВЕРКА НЕ ВЫПОЛНЕНА: не удалось скачать образ prom/prometheus" >&2 ;;
esac
exit $rc
