#!/bin/sh
set -u
umask 077

trace() {
  printf '__TRACE__ stage=%s\n' "$1"
}

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

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

safe_name() {
  printf '%s' "$1" |
    sed 's#[^A-Za-z0-9_.-]#_#g'
}

file_fact() {
  path="$1"
  key="$(safe_name "$path")"

  if [ -e "$path" ]; then
    fact "file.${key}.exists" true

    if [ -f "$path" ]; then
      size="$(
        wc -c < "$path" |
          tr -d ' '
      )"

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

      fact "file.${key}.size" "${size:-UNKNOWN}"
      fact "file.${key}.sha256" "${hash:-UNKNOWN}"
    fi
  else
    fact "file.${key}.exists" false
  fi
}

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

redact_config() {
  file="$1"

  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
    }
  ' "$file"
}

trace known_tool_inventory

KNOWN_PATHS="
/usr/local/sbin/router-egress-health-repair-watch.sh
/usr/local/sbin/router-egress-emergency-decision-hook.sh
/usr/local/sbin/router-egress-emergency-refresh.sh
/usr/local/sbin/router-egress-hmn-plan-top5.sh
/usr/local/sbin/router-egress-hmn-rebalance-top5-apply.sh
/usr/local/lib/router-egress-recovery-state.sh
/root/hmn/hmn-refresh-pool-safe.sh
/etc/router-egress-emergency-refresh.conf
/etc/init.d/router-egress-health-repair
/etc/init.d/router-egress-emergency-decision
/etc/init.d/router-egress-slots
/etc/init.d/router-egress-mapper
/etc/crontabs/root
/root/hmn/cache/ok-awg1-strict-foreign-latest.tsv
/var/lib/router-egress-recovery
"

for path in $KNOWN_PATHS; do
  file_fact "$path"
done

trace syntax_inventory

SCRIPT_PATHS="
/usr/local/sbin/router-egress-health-repair-watch.sh
/usr/local/sbin/router-egress-emergency-decision-hook.sh
/usr/local/sbin/router-egress-emergency-refresh.sh
/usr/local/sbin/router-egress-hmn-plan-top5.sh
/usr/local/sbin/router-egress-hmn-rebalance-top5-apply.sh
/usr/local/lib/router-egress-recovery-state.sh
/root/hmn/hmn-refresh-pool-safe.sh
/etc/init.d/router-egress-health-repair
/etc/init.d/router-egress-emergency-decision
/etc/init.d/router-egress-slots
/etc/init.d/router-egress-mapper
"

for path in $SCRIPT_PATHS; do
  key="$(safe_name "$path")"

  if [ -f "$path" ]; then
    if sh -n "$path"; then
      fact "syntax.${key}" true
    else
      fact "syntax.${key}" false
    fi
  else
    fact "syntax.${key}" missing
  fi
done

trace service_inventory

for service in \
  router-egress-health-repair \
  router-egress-emergency-decision \
  router-egress-slots \
  router-egress-mapper
do
  init="/etc/init.d/$service"

  if [ -x "$init" ]; then
    running="$(bool_cmd "$init" running)"
    enabled="$(bool_cmd "$init" enabled)"
  else
    running=false
    enabled=false
  fi

  fact "service.${service}.running" "$running"
  fact "service.${service}.enabled" "$enabled"
done

trace dependency_inventory

for command_name in \
  sh \
  awk \
  sed \
  grep \
  cut \
  sort \
  uniq \
  head \
  tail \
  wc \
  sha256sum \
  date \
  logger \
  flock \
  lock \
  uci \
  ubus \
  wg \
  ip \
  ping \
  nft \
  curl \
  wget
do
  if command -v "$command_name" >/dev/null 2>&1; then
    fact "command.${command_name}.exists" true
    fact "command.${command_name}.path" "$(
      command -v "$command_name"
    )"
  else
    fact "command.${command_name}.exists" false
  fi
done

trace safe_config_inventory

if [ -f /etc/router-egress-emergency-refresh.conf ]; then
  SAFE_CONFIG="$(
    redact_config /etc/router-egress-emergency-refresh.conf
  )"

  block emergency_refresh_config_redacted "$SAFE_CONFIG"

  COMMIT_VALUE="$(
    awk -F= '
      /^[[:space:]]*EMERGENCY_COMMIT_ENABLED[[:space:]]*=/ {
        value=$2
        sub(/[[:space:]#].*$/, "", value)
        gsub(/[[:space:]"\047]/, "", value)
        print value
        exit
      }
    ' /etc/router-egress-emergency-refresh.conf
  )"

  fact emergency_commit_enabled_raw "${COMMIT_VALUE:-UNSET}"
fi

trace cron_inventory

if [ -f /etc/crontabs/root ]; then
  RELEVANT_CRON="$(
    grep -nE \
      'router-egress|hmn|vpn|recovery|repair|refresh|rebalance|failopen|bootstrap' \
      /etc/crontabs/root \
      2>/dev/null ||
      true
  )"

  block relevant_cron "$RELEVANT_CRON"
fi

trace discovered_tool_inventory

DISCOVERED="$(
  {
    find /usr/local/sbin \
      /usr/local/lib \
      /etc/init.d \
      /root/hmn \
      -maxdepth 3 \
      -type f \
      2>/dev/null ||
      true
  } |
    grep -Ei \
      '(router-egress|hmn|health|repair|recovery|refresh|rebalance|failopen|bootstrap|quarantine|vpn)' |
    sort -u
)"

block discovered_tools "$DISCOVERED"

DISCOVERED_COUNT="$(
  printf '%s\n' "$DISCOVERED" |
    sed '/^$/d' |
    wc -l |
    tr -d ' '
)"

fact discovered_tool_count "$DISCOVERED_COUNT"

trace capability_source_scan

CAPABILITY_SCAN="$(
  grep -RniE \
    'EMERGENCY_COMMIT|DIRECT_FAILOPEN|BOOTSTRAP|DEGRADED|CONSOLIDAT|SLOT_EXHAUST|quarantine|daily.*repair|full.*refresh|retry.*interval|threshold|vpn1' \
    /usr/local/sbin/router-egress-* \
    /usr/local/lib/router-egress-* \
    /root/hmn/*.sh \
    /etc/router-egress-emergency-refresh.conf \
    /etc/init.d/router-egress-* \
    2>/dev/null ||
    true
)"

block capability_scan "$CAPABILITY_SCAN"

trace state_inventory

STATE_DIR="/var/lib/router-egress-recovery"

if [ -d "$STATE_DIR" ]; then
  STATE_FILES="$(
    find "$STATE_DIR" \
      -maxdepth 3 \
      -type f \
      2>/dev/null |
      sort
  )"

  block recovery_state_files "$STATE_FILES"

  STATE_FILE_COUNT="$(
    printf '%s\n' "$STATE_FILES" |
      sed '/^$/d' |
      wc -l |
      tr -d ' '
  )"

  fact recovery_state_file_count "$STATE_FILE_COUNT"
fi

HELPER="/usr/local/lib/router-egress-recovery-state.sh"

if [ -f "$HELPER" ]; then
  COUNTER="$(
    (
      unset REG_STATE_DIR
      . "$HELPER" || exit 71
      reg_daily_repair_get
    ) 2>/dev/null ||
    true
  )"

  fact repair_counter "${COUNTER:-UNKNOWN}"
fi

trace pool_inventory

POOL="/root/hmn/cache/ok-awg1-strict-foreign-latest.tsv"

if [ -f "$POOL" ]; then
  POOL_ROWS="$(
    wc -l < "$POOL" |
      tr -d ' '
  )"

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

  POOL_MTIME="$(
    stat -c '%Y' "$POOL" 2>/dev/null ||
      echo UNKNOWN
  )"

  fact pool_rows "$POOL_ROWS"
  fact pool_sha256 "$POOL_HASH"
  fact pool_mtime_epoch "$POOL_MTIME"
fi

trace runtime_inventory

for interface in vpn1 vpn2 vpn3 vpn4 vpn5; do
  exists=false
  endpoint="MISSING"
  strict=false

  if ip link show dev "$interface" >/dev/null 2>&1; then
    exists=true

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

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

    if ping \
      -I "$interface" \
      -c 1 \
      -W 4 \
      1.1.1.1 \
      >/dev/null 2>&1
    then
      strict=true
    fi
  fi

  fact "runtime.${interface}.exists" "$exists"
  fact "runtime.${interface}.endpoint" "$endpoint"
  fact "runtime.${interface}.strict" "$strict"
done

for table in 201 202 203 204 205; do
  route=false

  if ip route show table "$table" 2>/dev/null |
    grep -q '^default '
  then
    route=true
  fi

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

trace safe_dryrun_inventory

RUNNER="/usr/local/sbin/router-egress-emergency-refresh.sh"
PLANNER="/usr/local/sbin/router-egress-hmn-plan-top5.sh"
WATCHER="/usr/local/sbin/router-egress-health-repair-watch.sh"

if [ -x "$RUNNER" ]; then
  if RUNNER_JSON="$("$RUNNER" --dry-run 2>/dev/null)"; then
    fact runner_dryrun_ok true
    block runner_dryrun "$RUNNER_JSON"
  else
    fact runner_dryrun_ok false
  fi
fi

if [ -x "$PLANNER" ]; then
  if PLANNER_JSON="$("$PLANNER" 2>/dev/null)"; then
    fact planner_readonly_ok true
    block planner "$PLANNER_JSON"
  else
    fact planner_readonly_ok false
  fi
fi

if [ -x "$WATCHER" ]; then
  if WATCHER_JSON="$("$WATCHER" --dry-run --once 2>/dev/null)"; then
    fact watcher_dryrun_ok true
    block watcher_dryrun "$WATCHER_JSON"
  else
    fact watcher_dryrun_ok false
  fi
fi

trace firewall_inventory

NFT_RELEVANT="$(
  nft list ruleset 2>/dev/null |
    grep -niE \
      'direct|failopen|vpn1|vpn2|vpn3|vpn4|vpn5|0x20[1-5]|cs[1-5]' ||
    true
)"

block nft_relevant "$NFT_RELEVANT"

trace complete

fact production_modified false
fact refresh_ran false
fact rebalance_apply_ran false
fact direct_failopen_changed false
