#!/bin/sh
set -eu
umask 077

CONF="/etc/router-egress-emergency-refresh.conf"
RUNNER="/usr/local/sbin/router-egress-emergency-refresh.sh"
HOOK="/usr/local/sbin/router-egress-emergency-decision-hook.sh"
PLANNER="/usr/local/sbin/router-egress-hmn-plan-top5.sh"
REFRESH="/root/hmn/hmn-refresh-pool-safe.sh"
APPLY="/usr/local/sbin/router-egress-hmn-rebalance-top5-apply.sh"
HELPER="/usr/local/lib/router-egress-recovery-state.sh"
POOL="/root/hmn/cache/ok-awg1-strict-foreign-latest.tsv"
STATE_DIR="/var/lib/router-egress-recovery"

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"
}

block() {
  echo "__BLOCK_BEGIN__ $1"
  printf '%s\n' "$2"
  echo "__BLOCK_END__ $1"
}

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

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

commit_value() {
  (
    unset EMERGENCY_COMMIT_ENABLED
    . "$CONF"

    case "${EMERGENCY_COMMIT_ENABLED:-0}" in
      1|true|TRUE|yes|YES|on|ON)
        printf true
        ;;
      *)
        printf false
        ;;
    esac
  )
}

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

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

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

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

  return 1
}

endpoint_value() {
  interface="$1"

  wg show "$interface" endpoints 2>/dev/null |
    awk '
      NF >= 2 {
        print $NF
        exit
      }
    '
}

redact_config() {
  awk '
    /^[[:space:]]*#/ {
      print
      next
    }

    /^[[:space:]]*$/ {
      print
      next
    }

    /=/ {
      line=$0
      key=line
      sub(/=.*/, "", key)
      upper=toupper(key)

      if (
        upper ~ /PRIVATE/ ||
        upper ~ /PRESHARED/ ||
        upper ~ /PASSWORD/ ||
        upper ~ /PASSWD/ ||
        upper ~ /SECRET/ ||
        upper ~ /TOKEN/ ||
        upper ~ /ACCESS.*CODE/ ||
        upper ~ /API.*KEY/
      ) {
        print key "=REDACTED"
      } else {
        print line
      }

      next
    }

    {
      print
    }
  ' "$CONF"
}

echo "__TRACE__ stage=required_files"

for path in \
  "$CONF" \
  "$RUNNER" \
  "$HOOK" \
  "$PLANNER" \
  "$REFRESH" \
  "$APPLY" \
  "$HELPER" \
  "$POOL" \
  "$HOOK_INIT" \
  "$WATCHER_INIT"
do
  [ -e "$path" ] || {
    echo "__ERROR__ missing=$path"
    exit 21
  }
done

echo "__TRACE__ stage=config_and_services"

fact commit_enabled "$(commit_value)"
fact repair_counter "$(repair_counter)"

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)"

CONFIG_REDACTED="$(redact_config)"
block config_redacted "$CONFIG_REDACTED"

echo "__TRACE__ stage=runner_hook_planner"

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

json_block runner "$RUNNER_JSON"
json_block hook "$HOOK_JSON"
json_block planner "$PLANNER_JSON"

echo "__TRACE__ stage=pool_and_state"

fact pool_rows "$(
  wc -l < "$POOL" |
    tr -d ' '
)"

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

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

STATE_FILES="$(
  find "$STATE_DIR" \
    -maxdepth 3 \
    -type f \
    2>/dev/null |
    sort ||
  true
)"

block recovery_state_files "$STATE_FILES"

STATE_METADATA="$(
  for path in $STATE_FILES; do
    size="$(
      wc -c < "$path" 2>/dev/null |
        tr -d ' ' ||
      echo UNKNOWN
    )"

    hash="$(
      sha256sum "$path" 2>/dev/null |
        sed 's/[[:space:]].*$//' ||
      echo UNKNOWN
    )"

    mtime="$(
      date -r "$path" +%s 2>/dev/null ||
      echo UNKNOWN
    )"

    printf '%s\t%s\t%s\t%s\n' \
      "$path" \
      "$size" \
      "$hash" \
      "$mtime"
  done
)"

block recovery_state_metadata "$STATE_METADATA"

echo "__TRACE__ stage=runtime_slots"

STRICT_ALL=true

for interface in vpn1 vpn2 vpn3 vpn4 vpn5; do
  endpoint="$(endpoint_value "$interface")"

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

  fact "endpoint.${interface}" "$endpoint"

  if strict_ping "$interface"; then
    strict=true
  else
    strict=false
    STRICT_ALL=false
  fi

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

fact strict_all "$STRICT_ALL"

ROUTES_ALL=true

for table in 201 202 203 204 205; do
  if ip route show table "$table" 2>/dev/null |
    grep -q '^default '
  then
    route=true
  else
    route=false
    ROUTES_ALL=false
  fi

  fact "route.${table}" "$route"
done

fact routes_all "$ROUTES_ALL"

echo "__TRACE__ stage=process_and_lock_inventory"

PROCESSES="$(
  ps w 2>/dev/null |
    grep -E \
      'hmn-refresh-pool-safe|router-egress-hmn-rebalance-top5-apply|router-egress-emergency-refresh' |
    grep -v grep ||
  true
)"

block relevant_processes "$PROCESSES"

if [ -n "$PROCESSES" ]; then
  fact real_refresh_process_seen true
else
  fact real_refresh_process_seen false
fi

LOCKS="$(
  find /var/lock /tmp \
    -maxdepth 2 \
    -type f \
    2>/dev/null |
    grep -Ei \
      'router-egress|hmn|refresh|rebalance|vpn' |
    sort ||
  true
)"

block relevant_lock_files "$LOCKS"

echo "__TRACE__ stage=safety_confirmation"

fact production_modified false
fact vm101_modified false
fact refresh_ran false
fact rebalance_apply_ran false
fact counter_changed false
fact watcher_invoked false
fact direct_failopen_changed false

echo "__TRACE__ stage=complete"
