#!/usr/bin/env bash
set -euo pipefail

RUNTIME_ENV_FILE="${WELLAU_SSLVPN_RUNTIME_ENV_FILE:-$HOME/.config/wellau-sslvpn/runtime.env}"
if [[ -f "$RUNTIME_ENV_FILE" ]]; then
  # shellcheck disable=SC1090
  source "$RUNTIME_ENV_FILE"
fi

REPO_DIR="${SSLVPN_REPO_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
ENV_FILE="${WELLAU_SSLVPN_ENV_FILE:-$REPO_DIR/.env}"
if [[ -f "$ENV_FILE" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$ENV_FILE"
  set +a
fi

VPN_HOST="${WELLAU_VPN_GATEWAY:-vpn.wellau.com}"
VPN_USERNAME="${WELLAU_VPN_USERNAME:-}"
HK_ADMIN_HOST="internal-k8s-wellauhksub2apiad-5a69e59c8d-263820691.ap-east-1.elb.amazonaws.com"
CPA_SHARD_001_HOST="172.32.4.201"
CPA_SHARD_001_PORT="8317"
EXPECTED_ROUTES=("172.31.0.0/16" "172.32.0.0/16")
PING_TARGETS=("172.31.1.7" "172.32.1.89" "$CPA_SHARD_001_HOST")
TCP_TARGETS=("172.31.1.7:22" "172.32.1.89:22" "$CPA_SHARD_001_HOST:$CPA_SHARD_001_PORT")
CPA_L1_PROBE="http://$CPA_SHARD_001_HOST:$CPA_SHARD_001_PORT/v1/models"
CPA_L2_PROBE="http://$CPA_SHARD_001_HOST:$CPA_SHARD_001_PORT/v1/models"
HK_ADMIN_PROBE="http://$HK_ADMIN_HOST/admin"
CPA_L2_API_KEY_FILE="${WELLAU_CPA_SHARD_001_API_KEY_FILE:-$HOME/.config/wellau-sslvpn/cpa-shard-001-api-key}"
PING_TIMEOUT_SECONDS=4
TCP_TIMEOUT_SECONDS=6
HTTP_TIMEOUT_SECONDS=8
STATE_DIR="${WELLAU_VPN_STATE_DIR:-$HOME/.local/state/wellau-vpn}"
LAST_STATUS_FILE="$STATE_DIR/last-status"
EVENT_LOG_FILE="$STATE_DIR/events.log"


notify=false
if [[ "${1:-}" == "--notify" ]]; then
  notify=true
fi

ok=true
lines=()
lock_fd=200
mkdir -p "$STATE_DIR"
exec 200>"$STATE_DIR/status.lock"
if ! flock -n "$lock_fd"; then
  if [[ -s "$LAST_STATUS_FILE" ]]; then
    echo "INFO using cached status because another wellau-vpn-status check is already running"
    cat "$LAST_STATUS_FILE"
    cached_summary="$(grep -m1 '^SUMMARY ' "$LAST_STATUS_FILE" || true)"
    case "$cached_summary" in
      "SUMMARY OK"*) exit 0 ;;
      "SUMMARY DEGRADED"*|"SUMMARY FAIL"*) exit 1 ;;
      *) exit 2 ;;
    esac
  fi
  echo "SUMMARY UNKNOWN control=unknown data=unknown"
  echo "WARN another wellau-vpn-status check is already running"
  exit 2
fi

add_line() {
  lines+=("$1")
}

check_cmd() {
  command -v "$1" >/dev/null 2>&1
}

check_icmp() {
  local target="$1"
  local output rtt
  output="$(ping -c 2 -W "$PING_TIMEOUT_SECONDS" "$target" 2>/dev/null || true)"
  if grep -Eq '[12] received' <<<"$output"; then
    rtt="$(sed -n 's/^rtt .* = \([^ ]*\) ms$/\1/p' <<<"$output")"
    add_line "OK icmp $target reachable${rtt:+ rtt=$rtt ms}"
    return 0
  fi
  if [[ "$target" == "$HK_ADMIN_HOST" ]]; then
    add_line "INFO icmp $target no reply within ${PING_TIMEOUT_SECONDS}s; target is AWS ALB, HTTP /admin is authoritative"
  else
    add_line "WARN icmp $target no reply within ${PING_TIMEOUT_SECONDS}s"
  fi
  return 1
}

check_tcp() {
  local target="$1"
  local host port
  host="${target%:*}"
  port="${target#*:}"
  if timeout "$TCP_TIMEOUT_SECONDS" bash -lc "</dev/tcp/$host/$port" >/dev/null 2>&1; then
    add_line "OK tcp $target reachable"
    return 0
  fi
  add_line "WARN tcp $target not reachable within ${TCP_TIMEOUT_SECONDS}s"
  return 1
}

check_vpn_credentials() {
  if [[ -f "$ENV_FILE" ]]; then
    add_line "OK credential env exists: $ENV_FILE"
  else
    add_line "WARN credential env missing: $ENV_FILE"
    return 0
  fi
  if [[ -n "${VPN_USERNAME:-}" ]]; then
    add_line "OK VPN username configured: $VPN_USERNAME"
  else
    add_line "WARN VPN username is empty in $ENV_FILE"
  fi
  if [[ -n "${WELLAU_VPN_PASSWORD:-}" ]]; then
    add_line "OK VPN password configured in $ENV_FILE"
  else
    add_line "WARN VPN password is empty in $ENV_FILE"
  fi
  if [[ -n "${WELLAU_VPN_TOTP_SECRET:-}" ]]; then
    add_line "OK VPN TOTP secret configured in $ENV_FILE"
  else
    add_line "WARN VPN TOTP secret is empty in $ENV_FILE"
  fi
}

load_cpa_l2_api_key() {
  if [[ -n "${WELLAU_CPA_SHARD_001_API_KEY:-}" ]]; then
    printf '%s' "$WELLAU_CPA_SHARD_001_API_KEY"
    return 0
  fi
  if [[ -f "$CPA_L2_API_KEY_FILE" ]]; then
    sed -n '1p' "$CPA_L2_API_KEY_FILE" | tr -d '\r\n'
    return 0
  fi
  return 1
}

check_vpn_credentials

if pgrep -x openconnect >/dev/null 2>&1 || nmcli -t -f NAME,TYPE,STATE connection show --active 2>/dev/null | grep -q '^Wellau SSL VPN:vpn:activated$'; then
  add_line "OK openconnect/NetworkManager VPN process is active"
else
  add_line "FAIL no active openconnect or NetworkManager VPN connection found"
  ok=false
fi

if ip -brief addr show tun0 >/dev/null 2>&1; then
  add_line "OK tun0 exists: $(ip -brief addr show tun0 | tr -s ' ')"
else
  add_line "FAIL tun0 is missing"
  ok=false
fi

for route in "${EXPECTED_ROUTES[@]}"; do
  if ip route show "$route" 2>/dev/null | grep -q 'dev tun0'; then
    add_line "OK route $route via tun0"
  else
    add_line "FAIL route $route is not via tun0"
    ok=false
  fi
done

tunnel_hk=false
tunnel_us=false
tunnel_cpa=false

for target in "${PING_TARGETS[@]}"; do
  if check_icmp "$target"; then
    case "$target" in
      "172.31.1.7") tunnel_hk=true ;;
      "172.32.1.89") tunnel_us=true ;;
      "$CPA_SHARD_001_HOST") tunnel_cpa=true ;;
    esac
  fi
done

for target in "${TCP_TARGETS[@]}"; do
  if check_tcp "$target"; then
    case "$target" in
      "172.31.1.7:22") tunnel_hk=true ;;
      "172.32.1.89:22") tunnel_us=true ;;
      "$CPA_SHARD_001_HOST:$CPA_SHARD_001_PORT") tunnel_cpa=true ;;
    esac
  fi
done

service_failed=false

if check_cmd curl; then
  if timeout "$TCP_TIMEOUT_SECONDS" bash -lc "</dev/tcp/$HK_ADMIN_HOST/80" >/dev/null 2>&1; then
    add_line "OK tcp $HK_ADMIN_HOST:80 reachable"
  else
    add_line "WARN tcp $HK_ADMIN_HOST:80 not reachable within ${TCP_TIMEOUT_SECONDS}s"
    service_failed=true
  fi

  hk_admin_result="$(curl --noproxy '*' -sS --max-time "$HTTP_TIMEOUT_SECONDS" -w 'HTTP_STATUS=%{http_code}' "$HK_ADMIN_PROBE" 2>/dev/null || true)"
  if grep -q 'HTTP_STATUS=200' <<<"$hk_admin_result"; then
    add_line "OK HK admin HTTP probe returned 200"
  else
    add_line "WARN HK admin HTTP probe unexpected result within ${HTTP_TIMEOUT_SECONDS}s: ${hk_admin_result//$'\n'/ }"
    service_failed=true
  fi

  cpa_l1_result="$(curl --noproxy '*' -sS --max-time "$HTTP_TIMEOUT_SECONDS" -w 'HTTP_STATUS=%{http_code}' "$CPA_L1_PROBE" 2>/dev/null || true)"
  if grep -q 'HTTP_STATUS=401' <<<"$cpa_l1_result" && grep -q 'Missing API key' <<<"$cpa_l1_result"; then
    add_line "OK CPA shard 001 L1 online: unauthenticated auth challenge returned"
  else
    add_line "WARN CPA shard 001 L1 unexpected result within ${HTTP_TIMEOUT_SECONDS}s: ${cpa_l1_result//$'\n'/ }"
    service_failed=true
  fi

  if cpa_l2_api_key="$(load_cpa_l2_api_key)" && [[ -n "$cpa_l2_api_key" ]]; then
    cpa_l2_result="$(curl --noproxy '*' -sS --max-time "$HTTP_TIMEOUT_SECONDS" -H "Authorization: Bearer $cpa_l2_api_key" -w 'HTTP_STATUS=%{http_code}' "$CPA_L2_PROBE" 2>/dev/null || true)"
    if grep -q 'HTTP_STATUS=200' <<<"$cpa_l2_result"; then
      add_line "OK CPA shard 001 L2 API key probe returned 200"
    else
      add_line "WARN CPA shard 001 L2 API key probe unexpected result within ${HTTP_TIMEOUT_SECONDS}s: ${cpa_l2_result//$'\n'/ }"
      service_failed=true
    fi
  else
    add_line "WARN CPA shard 001 L2 API key probe skipped: set WELLAU_CPA_SHARD_001_API_KEY or $CPA_L2_API_KEY_FILE"
  fi
fi

control_failed=false
for line in "${lines[@]}"; do
  case "$line" in
    "FAIL no active openconnect"*|"FAIL tun0"*|"FAIL route"*) control_failed=true ;;
  esac
done

tunnel_data="ok"
if ! $tunnel_hk && ! $tunnel_us && ! $tunnel_cpa; then
  tunnel_data="fail"
elif ! $tunnel_hk || ! $tunnel_us || ! $tunnel_cpa; then
  tunnel_data="partial"
fi

service_state="ok"
if $service_failed; then
  service_state="degraded"
fi

summary="SUMMARY OK control=ok data=$tunnel_data service=$service_state"
if $control_failed && [[ "$tunnel_data" == "fail" ]]; then
  summary="SUMMARY FAIL control=fail data=fail service=$service_state"
elif $control_failed; then
  summary="SUMMARY FAIL control=fail data=$tunnel_data service=$service_state"
elif [[ "$tunnel_data" == "fail" ]]; then
  summary="SUMMARY DEGRADED control=ok data=fail service=$service_state"
elif [[ "$tunnel_data" == "partial" || "$service_state" == "degraded" ]]; then
  summary="SUMMARY DEGRADED control=ok data=$tunnel_data service=$service_state"
fi
lines=("$summary" "${lines[@]}")

printf '%s\n' "${lines[@]}" > "$LAST_STATUS_FILE"
if [[ "$summary" != SUMMARY\ OK* ]]; then
  {
    printf '%s %s\n' "$(date -Iseconds)" "$summary"
    printf '%s\n' "${lines[@]}"
  } >> "$EVENT_LOG_FILE"
fi

printf '%s\n' "${lines[@]}"

if $notify && check_cmd notify-send; then
  if [[ "$summary" == SUMMARY\ OK* ]]; then
    notify-send "Wellau SSL VPN" "VPN online: $VPN_HOST"
  else
    notify-send -u critical "Wellau SSL VPN" "$summary"
  fi
fi

if [[ "$summary" == SUMMARY\ OK* ]]; then
  exit 0
fi
exit 1
