#!/usr/bin/env bash
# Inside status for bank / exchange / merchant. Hard-capped SSH — never hang forever.
set -euo pipefail
ROOT=$(cd "$(dirname "$0")" && pwd)
# shellcheck source=lib.sh
source "$ROOT/lib.sh"

# Area inside-### — container / process state on koopa (SSH)
set_area inside
section "inside · collect from koopa"

if [ "${SKIP_SSH}" = "1" ]; then
  warn "ssh" "SKIP_SSH=1 — skipped"
  summary
  exit 0
fi

if ! koopa_ssh_ok; then
  err "ssh" "cannot reach ${KOOPA_SSH} in ${SSH_CONNECT_TIMEOUT}s — set SKIP_SSH=1 to skip inside"
  summary
  exit 1
fi
ok "ssh ${KOOPA_SSH}"

# One short remote script (≤ SSH_CMD_TIMEOUT). Every slow step is local curl -m 3 or quick pgrep.
RAW=$(
  koopa_ssh_bash "${SSH_CMD_TIMEOUT}" <<'REMOTE' || true
set +e
emit() { printf 'E|%s|%s|%s|%s\n' "$1" "$2" "$3" "$(printf '%s' "${4:-}" | tr '\n\r' '  ' | head -c 200)"; }
# quick curl
hc() { curl -skS -m 3 -o /tmp/mb -w '%{http_code}' "$1" 2>/dev/null || echo 000; }
# quick process check inside container (pgrep only)
hasp() { podman exec "$1" pgrep -f "$2" >/dev/null 2>&1; }

BANK=$(podman ps --format '{{.Names}}' 2>/dev/null | grep -iE 'hacktivism-bank|taler-bank' | head -1)
[ -z "$BANK" ] && BANK=$(podman ps --format '{{.Names}}' 2>/dev/null | grep -i bank | head -1)
EX=$(podman ps --format '{{.Names}}' 2>/dev/null | grep -i exchange | head -1)
MER=$(podman ps --format '{{.Names}}' 2>/dev/null | grep -E '^taler-hacktivism$' | head -1)
[ -z "$MER" ] && MER=$(podman ps --format '{{.Names}}' 2>/dev/null | grep -iE 'merchant|hacktivism' | grep -viE 'bank|exchange' | head -1)

# Domain resolve inside container (wirewatch needs bank.hacktivism.ch → real IP)
# emit: comp LEVEL dns "host → ip" or fail
check_dns() {
  local comp="$1" ctr="$2" host="$3"
  local line ip code
  # Prefer IPv4 (wirewatch/libcurl often happier; avoid dead AAAA)
  line=$(podman exec "$ctr" getent ahostsv4 "$host" 2>/dev/null | head -1)
  [ -z "$line" ] && line=$(podman exec "$ctr" getent hosts "$host" 2>/dev/null | head -1)
  ip=$(echo "$line" | awk '{print $1}')
  if [ -z "$ip" ]; then
    emit "$comp" ERROR "dns $host" "no resolve — run pin-container-hosts.sh"
    return 1
  fi
  # 127.0.0.1 is almost always wrong for public bank/exchange from inside pasta
  if [ "$ip" = "127.0.0.1" ] || [ "$ip" = "::1" ]; then
    emit "$comp" ERROR "dns $host" "$ip (loopback — wirewatch will fail)"
    return 1
  fi
  code=$(podman exec "$ctr" curl -skS -m 3 -o /dev/null -w '%{http_code}' "https://${host}/config" 2>/dev/null || echo 000)
  if [ "$code" = "200" ]; then
    emit "$comp" OK "dns $host" "→ $ip /config=$code"
  else
    emit "$comp" WARN "dns $host" "→ $ip /config=$code"
  fi
}

if [ -z "$BANK" ]; then emit bank ERROR container "not running"
else
  emit bank INFO container "$(podman ps --filter name=$BANK --format '{{.Names}} {{.Status}}' | head -1)"
  emit bank INFO ports "$(podman ps --filter name=$BANK --format '{{.Ports}}' | head -1)"
  hasp "$BANK" 'MainKt serve|libeufin-bank serve' && emit bank OK libeufin "running" || emit bank ERROR libeufin "not running — API/withdraw dead"
  podman exec "$BANK" pg_isready -q 2>/dev/null && emit bank OK postgres "ready" || emit bank ERROR postgres "not ready"
  c=$(hc http://127.0.0.1:9012/config)
  [ "$c" = "200" ] && emit bank OK "local /config" "HTTP $c" || emit bank ERROR "local /config" "HTTP $c"
  c=$(hc http://127.0.0.1:9012/taler-integration/config)
  [ "$c" = "200" ] && emit bank OK "local integration" "HTTP $c" || emit bank ERROR "local integration" "HTTP $c"
  hasp "$BANK" 'nginx' && emit bank OK nginx ":9013" || emit bank WARN nginx "not running"
  check_dns bank "$BANK" bank.hacktivism.ch || true
  check_dns bank "$BANK" exchange.hacktivism.ch || true
fi

if [ -z "$EX" ]; then emit exchange ERROR container "not running"
else
  emit exchange INFO container "$(podman ps --filter name=$EX --format '{{.Names}} {{.Status}}' | head -1)"
  c=$(hc http://127.0.0.1:9011/config)
  [ "$c" = "200" ] && emit exchange OK "local /config" "HTTP $c" || emit exchange ERROR "local /config" "HTTP $c"
  c=$(curl -sS -m 5 -o /dev/null -w '%{http_code}' http://127.0.0.1:9011/keys 2>/dev/null || echo 000)
  [ "$c" = "200" ] && emit exchange OK "local /keys" "HTTP $c" || emit exchange ERROR "local /keys" "HTTP $c"
  hasp "$EX" 'taler-exchange-httpd' && emit exchange OK httpd "running" || emit exchange ERROR httpd "not running"
  hasp "$EX" 'taler-exchange-wirewatch' && emit exchange OK wirewatch "running" || emit exchange ERROR wirewatch "not running — withdraw stuck after bank confirm"
  hasp "$EX" 'taler-exchange-aggregator' && emit exchange OK aggregator "running" || emit exchange WARN aggregator "not running"
  hasp "$EX" 'taler-exchange-transfer' && emit exchange OK transfer "running" || emit exchange WARN transfer "not running"
  # critical for wire gateway
  check_dns exchange "$EX" bank.hacktivism.ch || true
  check_dns exchange "$EX" exchange.hacktivism.ch || true
  check_dns exchange "$EX" taler.hacktivism.ch || true
fi

if [ -z "$MER" ]; then emit merchant ERROR container "not running"
else
  emit merchant INFO container "$(podman ps --filter name=$MER --format '{{.Names}} {{.Status}}' | head -1)"
  c=$(hc https://127.0.0.1:9010/config)
  [ "$c" = "200" ] && emit merchant OK "local /config" "HTTP $c" || emit merchant ERROR "local /config" "HTTP $c"
  hasp "$MER" 'taler-merchant-httpd' && emit merchant OK httpd "running" || emit merchant ERROR httpd "not running"
  hasp "$MER" 'taler-merchant-wirewatch' && emit merchant OK wirewatch "running" || emit merchant WARN wirewatch "not running"
  hasp "$MER" 'taler-merchant-depositcheck' && emit merchant OK depositcheck "running" || emit merchant WARN depositcheck "not running"
  check_dns merchant "$MER" bank.hacktivism.ch || true
  check_dns merchant "$MER" exchange.hacktivism.ch || true
  check_dns merchant "$MER" taler.hacktivism.ch || true
fi

if systemctl is-active caddy >/dev/null 2>&1 || pgrep -x caddy >/dev/null 2>&1; then
  emit caddy OK process "active"
else
  emit caddy ERROR process "not active"
fi
echo DONE
REMOTE
)

if [ -z "$RAW" ] || ! echo "$RAW" | grep -q '^E|'; then
  err "ssh" "remote timed out or empty (cap ${SSH_CMD_TIMEOUT}s)"
  summary
  exit 1
fi

while IFS= read -r line; do
  case "$line" in
    E\|*)
      IFS='|' read -r _ comp level key detail <<<"$line"
      case "$level" in
        OK)    ok "[$comp] $key${detail:+ ($detail)}" ;;
        ERROR) err "$comp" "$key" "$detail" ;;
        WARN)  warn "[$comp] $key" "$detail" ;;
        INFO)  info "[$comp] $key" "$detail" ;;
      esac
      ;;
  esac
done <<<"$RAW"

summary
