#!/bin/sh
set -u
umask 077

RUNNER="/usr/local/sbin/router-egress-emergency-refresh.sh"
PLANNER="/usr/local/sbin/router-egress-hmn-plan-top5.sh"
HELPER="/usr/local/lib/router-egress-recovery-state.sh"
CONF="/etc/router-egress-emergency-refresh.conf"
POOL="/root/hmn/cache/ok-awg1-strict-foreign-latest.tsv"

HOOK_INIT="/etc/init.d/router-egress-emergency-decision"
WATCHER_INIT="/etc/init.d/router-egress-health-repair"

fact() {
  printf '__FACT__ %s=%s\n' "$1" "$2"
}

json_block() {
  echo "__JSON_BEGIN__ $1"
  printf '%s\n' "$2"
  echo "__JSON_END__ $1"
}

block() {
  name="$1"
  shift

  echo "__BLOCK_BEGIN__ $name"
  "$@" 2>&1 || true
  echo "__BLOCK_END__ $name"
}

bool_cmd() {
  if "$@" >/dev/null 2>&1; then
    printf true
  else
    printf false
  fi
}

strict_iface() {
  interface="$1"
  attempt=1

  while [ "$attempt" -le 3 ]; do
    if ping \
      -I "$interface" \
      -c 1 \
      -W 3 \
      1.1.1.1 \
      >/dev/null 2>&1
    then
      return 0
    fi

    attempt=$((attempt + 1))
    sleep 1
  done

  return 1
}

routes_all() {
  for table in 201 202 203 204 205; do
    ip route show table "$table" 2>/dev/null |
      grep -q '^default ' ||
      return 1
  done

  return 0
}

state_value() {
  key="$1"
  fallback="$2"

  (
    unset REG_STATE_DIR
    . "$HELPER"
    reg_get_state "$key" "$fallback"
  )
}

repair_counter() {
  (
    unset REG_STATE_DIR
    . "$HELPER"
    reg_daily_repair_get
  )
}

for required in \
  "$RUNNER" \
  "$PLANNER" \
  "$HELPER" \
  "$CONF" \
  "$POOL"
do
  [ -f "$required" ] || {
    echo "__ERROR__ source_missing=$required"
    exit 21
  }
done

echo "__TRACE__ stage=cli_discovery"

for candidate in \
  awg \
  wg \
  amneziawg \
  amnezia-wg \
  amneziawg-go \
  wg-amnezia
do
  path="$(
    command -v "$candidate" 2>/dev/null ||
    true
  )"

  [ -n "$path" ] ||
    path="NOT_FOUND"

  fact "cli.${candidate}" "$path"
done

block matching_executables sh -c '
  for directory in /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin; do
    [ -d "$directory" ] || continue

    find "$directory" \
      -maxdepth 1 \
      -type f \
      2>/dev/null |
      grep -Ei "/(a?wg|amnezia|wireguard)" ||
    true
  done |
  sort -u
'

block installed_packages sh -c '
  opkg list-installed 2>/dev/null |
    grep -Ei "amnezia|wireguard|(^|-)wg($|-)|kmod.*wg" ||
  true
'

block kernel_modules sh -c '
  lsmod 2>/dev/null |
    grep -Ei "amnezia|wireguard|awg" ||
  true
'

block interface_link_details sh -c '
  for interface in vpn1 vpn2 vpn3 vpn4 vpn5; do
    echo "===== $interface ====="
    ip -details link show dev "$interface" 2>/dev/null || true
  done
'

block network_protocols sh -c '
  uci -q show network 2>/dev/null |
    grep -E \
      "^network\.vpn[1-5]=|^network\.vpn[1-5]\.proto=|wireguard_vpn[1-5]|amnezia" |
    grep -vE \
      "private_key|preshared_key" ||
  true
'

block ubus_interface_status sh -c '
  for interface in vpn1 vpn2 vpn3 vpn4 vpn5; do
    echo "===== $interface ====="
    ubus call "network.interface.$interface" status 2>/dev/null || true
  done
'

for candidate in awg wg amneziawg amnezia-wg wg-amnezia; do
  path="$(
    command -v "$candidate" 2>/dev/null ||
    true
  )"

  [ -n "$path" ] || continue

  echo "__BLOCK_BEGIN__ cli_probe_${candidate}"

  "$path" --version 2>&1 || true
  "$path" show 2>&1 || true

  for interface in vpn1 vpn2 vpn3 vpn4 vpn5; do
    echo "===== $interface ====="
    "$path" show "$interface" 2>&1 || true
  done

  echo "__BLOCK_END__ cli_probe_${candidate}"
done

echo "__TRACE__ stage=clock_and_schedule"

fact snapshot_epoch "$(date +%s)"
fact vm101_local_time "$(date '+%Y-%m-%dT%H:%M:%S%z')"
fact vm101_utc_time "$(date -u '+%Y-%m-%dT%H:%M:%SZ')"

fact etc_tz "$(
  tr '\r\n ' '_' < /etc/TZ 2>/dev/null ||
  echo UNAVAILABLE
)"

fact uci_timezone "$(
  uci -q get system.@system[0].timezone 2>/dev/null ||
  echo UNAVAILABLE
)"

fact uci_zonename "$(
  uci -q get system.@system[0].zonename 2>/dev/null ||
  echo UNAVAILABLE
)"

CRON_LINE="$(
  grep -E \
    '^[[:space:]]*20[[:space:]]+4[[:space:]]+\*[[:space:]]+\*[[:space:]]+\*[[:space:]]+' \
    /etc/crontabs/root \
    2>/dev/null |
  grep -F '/root/hmn/hmn-refresh-pool-safe.sh' |
  head -n1 ||
  true
)"

[ -n "$CRON_LINE" ] || {
  echo "__ERROR__ schedule_missing=20_4_daily_hmn_refresh"
  exit 22
}

fact cron_0420_found true

echo "__BLOCK_BEGIN__ exact_cron_line"
printf '%s\n' "$CRON_LINE"
echo "__BLOCK_END__ exact_cron_line"

echo "__TRACE__ stage=health_and_routes"

HEALTHY_COUNT=0

for interface in vpn1 vpn2 vpn3 vpn4 vpn5; do
  if strict_iface "$interface"; then
    value=true
    HEALTHY_COUNT=$((HEALTHY_COUNT + 1))
  else
    value=false
  fi

  fact "strict.${interface}" "$value"
done

fact healthy_vpn_slots "$HEALTHY_COUNT"

fact strict_all "$(
  if [ "$HEALTHY_COUNT" -eq 5 ]; then
    echo true
  else
    echo false
  fi
)"

fact routes_all "$(bool_cmd routes_all)"

block routes_200_205 sh -c '
  for table in 200 201 202 203 204 205; do
    echo "===== table $table ====="
    ip route show table "$table" 2>/dev/null || true
  done
'

echo "__TRACE__ stage=planner_state_and_pool"

PLANNER_JSON="$("$PLANNER")"
RUNNER_JSON="$("$RUNNER" --dry-run)"

json_block planner "$PLANNER_JSON"
json_block runner "$RUNNER_JSON"

fact hook_running "$(bool_cmd "$HOOK_INIT" running)"
fact hook_enabled "$(bool_cmd "$HOOK_INIT" enabled)"
fact watcher_running "$(bool_cmd "$WATCHER_INIT" running)"
fact watcher_enabled "$(bool_cmd "$WATCHER_INIT" enabled)"

fact emergency_lock_present "$(
  bool_cmd test -e /var/lock/router-egress-emergency-refresh.lock
)"

fact refresh_lock_present "$(
  bool_cmd test -e /tmp/hmn-refresh-pool-safe.lock
)"

fact state_mode "$(state_value mode UNKNOWN)"
fact state_status "$(
  state_value last_emergency_refresh_status UNKNOWN
)"
fact state_epoch "$(
  state_value last_emergency_refresh_epoch 0
)"
fact repair_counter "$(repair_counter)"

fact commit_raw "$(
  (
    . "$CONF"
    printf '%s' "${EMERGENCY_COMMIT_ENABLED:-UNSET}"
  )
)"

fact pool_sha256 "$(
  sha256sum "$POOL" |
    sed 's/[[:space:]].*$//'
)"

fact pool_rows "$(
  sed '1d' "$POOL" |
    grep -c . ||
  true
)"

fact pool_mtime_epoch "$(date -r "$POOL" +%s)"

LATEST_GENERATION="$(
  readlink -f /root/hmn/configs/awg1/latest 2>/dev/null ||
  true
)"

[ -n "$LATEST_GENERATION" ] ||
  LATEST_GENERATION="UNRESOLVED"

fact latest_generation "$LATEST_GENERATION"

block cron_log_tail sh -c '
  tail -n 400 \
    /root/hmn/logs/hmn-refresh-pool-cron.log \
    2>/dev/null ||
  true
'

block emergency_log_tail sh -c '
  tail -n 400 \
    /var/log/router-egress-emergency-refresh.log \
    2>/dev/null ||
  true
'

block filesystem_usage df -Pk

fact read_only true
fact refresh_ran false
fact rebalance_ran false
fact network_changed false
fact services_changed false
fact state_changed false
fact timer_changed false
fact plan_changed false
fact direct_failopen_changed false

echo "__TRACE__ stage=complete"

[ "$HEALTHY_COUNT" -eq 5 ] || exit 31
[ "$(bool_cmd routes_all)" = true ] || exit 32

exit 0
