#!/usr/bin/env bash
# Nasazení předdefinovaného profilu 1–9: zapíše terkom-diagnostic.runtime.yaml,
# nastaví interval systemd timeru (20 / 10 / 5 s dle NORMAL / FAST / ULTRA) a restartuje timer + jednorázově službu.
# Vyžaduje root (sudo).
#
# Dostupné profily:
#   1  Standard                         20s  NORMAL
#   2  Výdejní freeze protection        10s  FAST
#   3  Network diagnostic / Čáslav      20s  NORMAL
#   4  Konzervativní monitoring         20s  NORMAL
#   5  Servisní agresivní                5s  ULTRA
#   6  Legacy: špička provozu           10s  FAST
#   7  Legacy: laboratoř                 5s  ULTRA
#   8  Legacy: kompromis                10s  FAST
#   9  Legacy: rychlý síť-only reboot   10s  FAST
#
# Hlavní profily jsou 1–5. Profily 6–9 zůstávají jako legacy/advanced volby kvůli zpětné kompatibilitě.
#
# Zvol číslo profilu (1–9) a spusť: sudo bash apply_diagnostic_profile.sh --from-descriptor "$0"
# nebo předej přímo: sudo bash apply_diagnostic_profile.sh 2
#

if [ -z "${BASH_VERSION:-}" ]; then
    if [ -f "$0" ]; then exec bash "$0" "$@"; fi
    echo "[ERROR] Vyžaduje bash. Spusť: curl -fsSL URL | sudo bash" >&2; exit 1
fi
set -euo pipefail

ACTIVE_PROFILE=1   # ← ZDE ZMĚŇ ČÍSLO PROFILU (1–9)

TERKOM_HOME="${TERKOM_HOME:-/opt/terkom-ng/terkom}"
RUNTIME="${RUNTIME:-$TERKOM_HOME/terkom-diagnostic.runtime.yaml}"
TIMER="${TIMER:-/etc/systemd/system/terkom-diagnostic.timer}"
DIAG_SERVICE="${DIAG_SERVICE:-terkom-diagnostic.service}"
DIAG_TIMER="${DIAG_TIMER:-terkom-diagnostic.timer}"
ACTIVE_PROFILE_FILE="${ACTIVE_PROFILE_FILE:-$TERKOM_HOME/terkom-diagnostic.active-profile}"
CONFIG_FILE="${CONFIG_FILE:-$TERKOM_HOME/config-local.yaml}"
DIAG_SCRIPT="${DIAG_SCRIPT:-$TERKOM_HOME/scripts/terkom-diagnostic.sh}"
NOTIFY_ENV_FILE="${NOTIFY_ENV_FILE:-$TERKOM_HOME/.terdiag-notify.env}"

die() { echo "[ERR] $*" >&2; exit 1; }

# Detekce jména Terkom systemd unit (bez hardkódování)
_detect_terkom_service() {
    local svc found
    svc="${TERKOM_SERVICE:-}"
    if [ -n "$svc" ] && systemctl cat "$svc" &>/dev/null; then echo "$svc"; return; fi

    # "service" může být skutečné jméno unit souboru na některých zařízeních
    for _c in terkom-ng-server terkom-ng terkom-server terkom kiosk service; do
        if systemctl cat "$_c" &>/dev/null; then echo "$_c"; return; fi
    done

    # list-units --all: zahrnuje zastavené i failed unity
    found="$(systemctl list-units --all --type=service --no-legend 2>/dev/null \
        | awk '{print $1}' | grep -iE 'terkom|kiosk' | grep -v 'terkom-diagnostic' | head -1 || true)"
    [ -n "$found" ] && systemctl cat "$found" &>/dev/null && { echo "$found"; return; }

    # list-unit-files: všechny nakonfigurované unity bez ohledu na stav
    found="$(systemctl list-unit-files --type=service --no-legend 2>/dev/null \
        | awk '{print $1}' | grep -iE 'terkom|kiosk' | grep -v 'terkom-diagnostic' | head -1 || true)"
    [ -n "$found" ] && systemctl cat "$found" &>/dev/null && { echo "$found"; return; }

    echo ""
}

# Aktualizuj marker DIAG_v{ver}_P{N} v config-local.yaml
_update_dia_marker() {
    local profile_id="$1"

    local version=""
    if [ -f "$DIAG_SCRIPT" ]; then
        version="$(grep -m1 '^SCRIPT_VERSION=' "$DIAG_SCRIPT" 2>/dev/null \
            | tr -d '"'"'" | cut -d= -f2 | xargs || true)"
    fi
    if [ -z "$version" ]; then
        echo "[WARN] Verze watchdogu nezjistitelná — marker v config-local.yaml nebude aktualizován."
        return
    fi

    local ai_mail_enabled="false"
    if [ -f "$NOTIFY_ENV_FILE" ]; then
        ai_mail_enabled="$(grep -E '^AI_REPORT_MAIL_ENABLED=' "$NOTIFY_ENV_FILE" 2>/dev/null | tail -1 | cut -d= -f2- | tr -d "\"'" | xargs || true)"
    fi
    local mail_marker="OFF"
    case "$(printf '%s' "$ai_mail_enabled" | tr '[:upper:]' '[:lower:]')" in
        true|1|yes|on) mail_marker="ON" ;;
    esac
    local new_marker="DIAG_v${version}_P${profile_id}_mail_${mail_marker}"

    if [ ! -f "$CONFIG_FILE" ]; then
        echo "[INFO] config-local.yaml nenalezen — marker přeskočen."
        return
    fi

    if grep -qE '"?description"?[[:space:]]*:.*DIAG_v' "$CONFIG_FILE" 2>/dev/null; then
        sed -i "s/DIAG_v[^ \"']*/${new_marker}/g" "$CONFIG_FILE"
        echo "[OK] Marker v config-local.yaml: ${new_marker}"
    elif grep -q '---DIA_v' "$CONFIG_FILE" 2>/dev/null; then
        sed -i "s/---DIA_v[^ \"']*/ ${new_marker}/g" "$CONFIG_FILE"
        echo "[OK] Starý marker ---DIA_v* migrován na: ${new_marker}"
    elif grep -q '---DIAGNOSTIKA' "$CONFIG_FILE" 2>/dev/null; then
        sed -i "s/---DIAGNOSTIKA/ ${new_marker}/g" "$CONFIG_FILE"
        echo "[OK] Starý marker ---DIAGNOSTIKA migrován na: ${new_marker}"
    else
        echo "[INFO] Žádný DIA marker v config-local.yaml — marker nepřidán (spusť install_diagnostic.sh)."
    fi
}

# Restart Terkomu po změně profilu (aby načetl nový marker z config-local.yaml)
_restart_terkom_for_profile() {
    local svc
    svc="$(_detect_terkom_service)"
    if [ -z "$svc" ]; then
        echo "[WARN] Terkom service nenalezena — restartuj ručně:"
        echo "       sudo systemctl list-units --type=service | grep -iE 'terkom|kiosk'"
        return
    fi
    echo "[INFO] Restart Terkomu ($svc) — načtení nového markeru..."
    systemctl stop "$svc" || true
    killall node 2>/dev/null || true
    sleep 2
    systemctl reset-failed "$svc" 2>/dev/null || true
    if systemctl start "$svc"; then
        sleep 2
        if systemctl is-active --quiet "$svc"; then
            echo "[OK] Terkom ($svc) spuštěn — nový marker načten."
        else
            echo "[WARN] start vrátil 0, ale unit není active. Zkus: sudo systemctl restart $svc"
        fi
    else
        echo "[WARN] Nepodařilo se spustit Terkom ($svc). Ručně: sudo systemctl restart $svc"
    fi
}

remount_rw() {
    mount -o remount,rw / 2>/dev/null || true
    mount -o remount,rw /boot 2>/dev/null || true
}
remount_ro() {
    sync || true
    mount -o remount,ro /boot 2>/dev/null || true
    mount -o remount,ro / 2>/dev/null || true
}

usage() {
    cat <<'HELP'
Použití: sudo apply_diagnostic_profile.sh <1-9|list|help|--from-descriptor [soubor]>

  list, help          — tabulka profilů (česky)
  1 … 5               — hlavní profily pro běžné nasazení
  6 … 9               — legacy/advanced profily ponechané kvůli kompatibilitě
                       Každý profil zapíše runtime YAML, daemon-reload, restart timeru a diagnostické služby.
  --from-descriptor   — přečte ACTIVE_PROFILE=N z deskriptoru (stdin nebo soubor)

Proměnné (volitelné):
  TERKOM_HOME         výchozí /opt/terkom-ng/terkom
  RUNTIME, TIMER, DIAG_SERVICE, DIAG_TIMER
  ACTIVE_PROFILE_FILE výchozí $TERKOM_HOME/terkom-diagnostic.active-profile

Příklad ze serveru (SSH):
  ssh pi@TERMINAL 'sudo curl -fsSL https://cdn.public.altisima.cz/diagnostika/apply_diagnostic_profile.sh | sudo bash -s -- 2'

Příklad nasazení přes deskriptor ze serveru:
  ssh pi@TERMINAL 'sudo bash -s' <<'EOF'
  # === DOSTUPNÉ PROFILY ===
  # 1 — Standard (20s, NORMAL)
  # 2 — Výdejní freeze protection (10s, FAST)
  # 3 — Network diagnostic / Čáslav (20s, NORMAL)
  # 4 — Konzervativní monitoring (20s, NORMAL)
  # 5 — Servisní agresivní (5s, ULTRA)
  ACTIVE_PROFILE=2
  EOF
HELP
}
 
list_profiles() {
    cat <<'LIST'
Profil  Timer  Režim   Stručný popis
──────  ─────  ─────   ─────────────────────────────────────────────────────────
   1     20s   NORMAL  Standard: běžné terminály, restart Terkom po 1 dead failu, reboot po 3.
   2     10s   FAST    Výdejní freeze protection: Barrandov, rychlý restart Terkomu a reboot po 2 dead/local UI failech.
   3     20s   NORMAL  Network diagnostic: Čáslav, lokálně OK, řeší se remote TCP / server / síť.
   4     20s   NORMAL  Konzervativní monitoring: pomalejší reakce, delší doba před rebootem, méně mailů.
   5      5s   ULTRA   Servisní agresivní: krátkodobé testování pod dohledem.
   6     10s   FAST    Legacy: špička provozu, síť-only reboot po 6 cyklech.
   7      5s   ULTRA   Legacy: původní laboratoř / ultra agresivní profil.
   8     10s   FAST    Legacy: původní kompromis, síť-only reboot po 5 cyklech.
   9     10s   FAST    Legacy: rychlý síť-only reboot; network restart po 2, reboot po 3.

Všechny profily používají recovery_profile: custom a lock_recovery_thresholds: true,
takže FAST/ULTRA v runtime nepřepíše prahy z YAML (vyžaduje diagnostiku z install ≥ 2.2.1 s touto logikou).
Nové incidentové limity v runtime YAML se naplno projeví po nasazení recovery logiky, která je čte.
LIST
}

write_timer() {
    local sec="$1"
    cat >"$TIMER" <<EOF
[Unit]
Description=Run Terkom Diagnostic V2 every ${sec} seconds

[Timer]
OnBootSec=20
OnUnitActiveSec=${sec}
AccuracySec=3
Unit=terkom-diagnostic.service

[Install]
WantedBy=timers.target
EOF
    chown root:root "$TIMER"
    chmod 644 "$TIMER"
}

write_runtime() {
    cat >"$RUNTIME" <<'YAML'
terkom_diagnostic:
  recovery_profile: custom
  lock_recovery_thresholds: true
  diag_mode: __DIAG_MODE__
  email_policy: all
  email_throttle_seconds: __EMAIL_THROTTLE__
  service_restart_after_fails: __SR__
  network_restart_after_fails: __NR__
  reboot_after_fails: __RB__
  service_restart_cooldown_seconds: __SCD__
  network_restart_cooldown_seconds: __NCD__
  reboot_cooldown_seconds: __RCD__
  min_failure_duration_before_reboot: __MIN_DUR__
  snapshot_cooldown_seconds: __SNAP__
  network_only_reboot_after_fails: __NOR__
  max_service_restarts_per_incident: 1
  max_network_restarts_per_incident: 2
  max_reboots_per_incident: 1
  dead_reboot_after_failed_service_restart: true
  local_ui_fail_fast_reboot: true
  remote_tcp_no_loop_recovery: true
YAML
}

fill_template() {
    local mode="$1" throttle="$2" sr="$3" nr="$4" rb="$5" scd="$6" ncd="$7" rcd="$8" min_dur="$9" snap="${10}" nor="${11}"
    write_runtime
    sed -i \
        -e "s/__DIAG_MODE__/$mode/" \
        -e "s/__EMAIL_THROTTLE__/$throttle/" \
        -e "s/__SR__/$sr/" \
        -e "s/__NR__/$nr/" \
        -e "s/__RB__/$rb/" \
        -e "s/__SCD__/$scd/" \
        -e "s/__NCD__/$ncd/" \
        -e "s/__RCD__/$rcd/" \
        -e "s/__MIN_DUR__/$min_dur/" \
        -e "s/__SNAP__/$snap/" \
        -e "s/__NOR__/$nor/" \
        "$RUNTIME"
}

apply_id() {
    local id="$1" timer_sec mode
    case "$id" in
        1)
            timer_sec=20 mode=NORMAL
            fill_template NORMAL 600 1 2 3 45 60 1200 90 120 0
            ;;
        2)
            timer_sec=10 mode=FAST
            fill_template FAST 300 1 2 2 20 30 900 45 60 0
            ;;
        3)
            timer_sec=20 mode=NORMAL
            fill_template NORMAL 600 1 2 4 60 60 1800 120 120 6
            ;;
        4)
            timer_sec=20 mode=NORMAL
            fill_template NORMAL 1200 2 3 5 120 120 3600 300 300 0
            ;;
        5)
            timer_sec=5 mode=ULTRA
            fill_template ULTRA 120 1 1 2 10 15 600 30 30 2
            ;;
        6)
            timer_sec=10 mode=FAST
            fill_template FAST 360 1 2 2 20 35 450 35 35 6
            ;;
        7)
            timer_sec=5 mode=ULTRA
            fill_template ULTRA 120 1 1 1 10 10 180 15 15 0
            ;;
        8)
            timer_sec=10 mode=FAST
            fill_template FAST 420 1 2 2 25 40 480 40 45 5
            ;;
        9)
            timer_sec=10 mode=FAST
            fill_template FAST 300 1 2 2 15 20 300 25 30 3
            ;;
        *)
            die "Neznámý profil: $id (očekáváno 1–9, list nebo help)"
            ;;
    esac

    chown root:root "$RUNTIME"
    chmod 644 "$RUNTIME"
    write_timer "$timer_sec"

    # Ulož číslo aktivního profilu pro diag_info / update
    echo "$id" > "$ACTIVE_PROFILE_FILE"
    chown root:root "$ACTIVE_PROFILE_FILE"
    chmod 644 "$ACTIVE_PROFILE_FILE"

    systemctl daemon-reload
    systemctl restart "$DIAG_TIMER"
    systemctl restart "$DIAG_SERVICE" || true
    echo "[OK] Profil $id nasazen: DIAG_MODE=$mode, timer=${timer_sec}s, runtime=$RUNTIME"
    echo "[OK] Aktivní profil uložen do: $ACTIVE_PROFILE_FILE"

    # Aktualizuj marker ---DIA_v{ver}_P{N} v config-local.yaml a restartuj Terkom
    _update_dia_marker "$id"
    _restart_terkom_for_profile
}

read_descriptor() {
    # Přečte ACTIVE_PROFILE=N ze souboru nebo stdin, ignoruje komentáře a prázdné řádky
    local src="${1:-}"
    local line profile_val=""
    if [ -n "$src" ]; then
        [ -f "$src" ] || die "Deskriptor nenalezen: $src"
        while IFS= read -r line; do
            case "$line" in
                '#'*|'') continue ;;
                ACTIVE_PROFILE=*) profile_val="${line#ACTIVE_PROFILE=}"; profile_val="$(echo "$profile_val" | xargs)" ;;
            esac
        done < "$src"
    else
        while IFS= read -r line; do
            case "$line" in
                '#'*|'') continue ;;
                ACTIVE_PROFILE=*) profile_val="${line#ACTIVE_PROFILE=}"; profile_val="$(echo "$profile_val" | xargs)" ;;
            esac
        done
    fi
    echo "$profile_val"
}

main() {
    local cmd="${1:-}"
    [ -n "$cmd" ] || { usage; exit 1; }
    case "$(echo "$cmd" | tr '[:upper:]' '[:lower:]')" in
        list|help|-h|--help)
            list_profiles
            exit 0
            ;;
    esac
    [ "$(id -u)" -eq 0 ] || die "Spusť jako root (sudo)."
    [ -d "$TERKOM_HOME" ] || die "Chybí $TERKOM_HOME — je diagnostika nainstalovaná?"

    trap remount_ro EXIT
    remount_rw

    # --from-descriptor: přečte ACTIVE_PROFILE=N ze souboru nebo stdin
    if [ "$cmd" = "--from-descriptor" ]; then
        local desc_src="${2:-}"
        local profile_id
        profile_id="$(read_descriptor "$desc_src")"
        [ -n "$profile_id" ] || die "Deskriptor neobsahuje řádek ACTIVE_PROFILE=<číslo>."
        case "$profile_id" in
            ''|*[!0-9]*) die "ACTIVE_PROFILE musí být číslo 1–9, dostal jsem: $profile_id" ;;
        esac
        [ "$profile_id" -ge 1 ] && [ "$profile_id" -le 9 ] || die "ACTIVE_PROFILE musí být 1–9, dostal jsem: $profile_id"
        echo "[INFO] Nasazuji profil ${profile_id} z deskriptoru..."
        apply_id "$profile_id"
        return
    fi

    case "$cmd" in
        ''|*[!0-9]*) die "Neplatný argument: $cmd" ;;
    esac
    [ "$cmd" -ge 1 ] && [ "$cmd" -le 9 ] || die "Profil musí být 1–9, dostal jsem: $cmd"
    apply_id "$cmd"
}

main "${1:-}" "${2:-}"
