#!/bin/bash
# =============================================================================
# network-status.sh -- Network Status Monitor
# =============================================================================
# Category: network | Bird: hawk | Tier: 2 | Node-aware: yes
# Absorbs: network-wireguard.sh, network-dns.sh, network-tls.sh,
#          network-traffic.sh, network-ssh.sh (status parts)
#
# Actions:
#   --status        JSON pill
#   --wireguard     WireGuard mesh status
#   --dns           DNS resolution checks
#   --tls           TLS certificate status
#   --ports         Listening ports
#   --connectivity  Inter-node connectivity test
#   --send          Full network status
#   --digest        Full report
#   --flush         Clear logs
# =============================================================================

TOOL_NAME="network-status"
TOOL_VERSION="3.0.0"
TOOL_TIER=2
TOOL_BIRD="hawk"
TOOL_LOG="/opt/binary/logs/tools/${TOOL_NAME}.log"

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [[ -f "${SCRIPT_DIR}/common.sh" ]]; then source "${SCRIPT_DIR}/common.sh"
elif [[ -f "${SCRIPT_DIR}/../common.sh" ]]; then source "${SCRIPT_DIR}/../common.sh"
else echo "FATAL: common.sh not found" >&2; exit 1; fi
export BIRD_ID="${TOOL_BIRD}"

FLEET_ENV="/etc/binary/fleet.env"
[ -f "$FLEET_ENV" ] && source "$FLEET_ENV" 2>/dev/null

FLEET_NODES=("${FLEET_ALPHA_IP:-10.69.69.1}" "${FLEET_BRAVO_IP:-10.69.69.3}" "${FLEET_CHARLIE_IP:-10.69.69.4}" "${FLEET_DELTA_IP:-10.69.69.5}" "${FLEET_ECHO_IP:-10.69.69.6}")
FLEET_NAMES=("alpha" "bravo" "charlie" "delta" "echo")
DNS_DOMAINS=("365hosting.org" "365email.org" "365entertainment.org")

_do_wireguard_impl() {
    echo "=== WireGuard: ${NODE_ID} ==="
    if command -v wg &>/dev/null; then
        local iface; iface=$(wg show interfaces 2>/dev/null | head -1)
        if [ -n "$iface" ]; then
            echo "  Interface: ${iface}"
            echo "  Peers:"
            wg show "$iface" 2>/dev/null | grep -E "(peer|endpoint|latest)" | sed 's/^/    /'
        else echo "  No active WireGuard interface"; fi
    else echo "  WireGuard not installed"; fi
}

_do_dns_impl() {
    echo "=== DNS: ${NODE_ID} ==="
    for d in "${DNS_DOMAINS[@]}"; do
        local r; r=$(dig @127.0.0.1 "$d" A +short +time=2 +tries=1 2>/dev/null)
        if [ -n "$r" ]; then echo "  [OK] ${d} -> ${r}"
        else echo "  [FAIL] ${d} failed to resolve"; fi
    done
}

_do_tls_impl() {
    echo "=== TLS: ${NODE_ID} ==="
    for d in "${DNS_DOMAINS[@]}"; do
        local exp; exp=$(echo | openssl s_client -servername "$d" -connect "${d}:443" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
        if [ -n "$exp" ]; then echo "  [OK] ${d}: expires ${exp}"
        else echo "  [SKIP] ${d}: no TLS or unreachable"; fi
    done
    # Local certs
    find /etc/letsencrypt/live 2>/dev/null -name "cert.pem" | head -5 | while read -r f; do
        local cn exp; cn=$(openssl x509 -noout -subject -in "$f" 2>/dev/null | sed 's/.*CN = //')
        exp=$(openssl x509 -noout -enddate -in "$f" 2>/dev/null | cut -d= -f2)
        echo "  ${cn}: ${exp}"
    done
}

_do_ports_impl() {
    echo "=== Ports: ${NODE_ID} ==="
    ss -tlnp 2>/dev/null | head -30
}

_do_connectivity_impl() {
    echo "=== Connectivity: ${NODE_ID} ==="
    for i in "${!FLEET_NODES[@]}"; do
        local ip="${FLEET_NODES[$i]}" name="${FLEET_NAMES[$i]}"
        if ping -c1 -W2 "$ip" &>/dev/null; then echo "  [OK] ${name} (${ip})"
        else echo "  [FAIL] ${name} (${ip}) unreachable"; fi
    done
}

_do_send_impl() {
    echo "=== Network Status: $(ts_local) ==="
    echo "  Node: ${NODE_ID}"
    echo ""
    _do_wireguard_impl; echo ""
    _do_dns_impl; echo ""
    _do_ports_impl
    tool_audit "send" "node=${NODE_ID}"
}

_do_status_impl() {
    local wg="false" dns_ok=0 dns_fail=0
    command -v wg &>/dev/null && wg show interfaces &>/dev/null && wg="true"
    for d in "${DNS_DOMAINS[@]}"; do
        if dig @127.0.0.1 "$d" A +short +time=1 +tries=1 &>/dev/null; then dns_ok=$((dns_ok+1))
        else dns_fail=$((dns_fail+1)); fi
    done
    local s="healthy"; [ "$dns_fail" -gt 0 ] && s="degraded"; [ "$wg" = "false" ] && s="degraded"
    echo "{\"tool\":\"${TOOL_NAME}\",\"node\":\"${NODE_ID}\",\"status\":\"${s}\",\"wireguard\":${wg},\"dns_ok\":${dns_ok},\"dns_fail\":${dns_fail},\"checked_at\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}"
}

_do_digest_impl() {
    echo "=== Network Report: ${NODE_ID} ==="; echo ""
    _do_send_impl; echo ""
    _do_tls_impl; echo ""
    _do_connectivity_impl
}

_do_flush_impl() { [ -f "$TOOL_LOG" ] && truncate -s 0 "$TOOL_LOG"; echo "Flush complete"; }

tool_help() {
    echo "${TOOL_NAME} v${TOOL_VERSION} -- Network Status Monitor"
    echo "  --wireguard|--dns|--tls|--ports|--connectivity"
    echo "  --status|--send|--digest|--flush"
}

do_send()   { tool_wrap "send"   _do_send_impl "$@"; }
do_status() { tool_wrap "status" _do_status_impl "$@"; }
do_digest() { tool_wrap "digest" _do_digest_impl "$@"; }
do_flush()  { tool_wrap "flush"  _do_flush_impl "$@"; }

tool_init; trap 'tool_complete' EXIT
case "${1:---help}" in
    --send) shift; do_send "$@" ;; --status) shift; do_status "$@" ;;
    --digest) shift; do_digest "$@" ;; --flush) shift; do_flush "$@" ;;
    --wireguard) _do_wireguard_impl ;; --dns) _do_dns_impl ;;
    --tls) _do_tls_impl ;; --ports) _do_ports_impl ;;
    --connectivity) _do_connectivity_impl ;; --help) tool_help ;;
    *) handle_standard_command "$@" ;;
esac
