#!/usr/bin/env bash
# MOMO Pro health monitor (110 cron -> 188 app).
#
# Public route health is the first source of truth. The 188 local endpoint and
# container state are secondary evidence only when the public health endpoint
# fails. This prevents the old reboot-era false positive that checked the 188
# root path and sent Telegram every five minutes while the real public service
# had already recovered.

set -euo pipefail

SECRETS_FILE="${SECRETS_FILE:-/etc/awoooi-ops/secrets.env}"
if [[ -r "$SECRETS_FILE" ]]; then
    # shellcheck source=/dev/null
    source "$SECRETS_FILE"
fi

: "${HEALTH_URL:=https://mo.wooo.work/health}"
: "${REMOTE_HOST:=192.168.0.188}"
: "${REMOTE_USER:=ollama}"
: "${REMOTE_LOCAL_URL:=http://127.0.0.1:5003/health}"
: "${CONTAINER_NAME:=momo-pro-system}"
: "${CURL_TIMEOUT:=15}"
: "${SEND_COOLDOWN_SECONDS:=1800}"
: "${COOLDOWN_FILE:=/tmp/momo-pro-health-monitor.cooldown}"
: "${NOTIFY_AWOOI_OPS_SCRIPT:=/home/wooo/awoooi-ops/notify-awoooi-ops.sh}"
: "${SSH_STRICT_HOST_KEY_CHECKING:=accept-new}"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S %z')] $*"
}

http_code_for() {
    local url="$1"
    curl -kLsS -o /dev/null -w "%{http_code}" \
        --connect-timeout "$CURL_TIMEOUT" \
        --max-time "$CURL_TIMEOUT" \
        "$url" 2>/dev/null || echo "000"
}

is_success_code() {
    case "$1" in
        2*|3*) return 0 ;;
        *) return 1 ;;
    esac
}

in_cooldown() {
    [[ -f "$COOLDOWN_FILE" ]] || return 1
    local last now elapsed
    last=$(cat "$COOLDOWN_FILE" 2>/dev/null || echo 0)
    now=$(date +%s)
    elapsed=$(( now - last ))
    if (( elapsed < SEND_COOLDOWN_SECONDS )); then
        log "COOLDOWN: last alert ${elapsed}s ago; skip Telegram (${SEND_COOLDOWN_SECONDS}s window)"
        return 0
    fi
    return 1
}

mark_cooldown() {
    date +%s > "$COOLDOWN_FILE"
}

send_ops_alert() {
    local alertname="$1"
    local summary="$2"
    local detail="$3"

    if in_cooldown; then
        return 0
    fi

    if [[ ! -x "$NOTIFY_AWOOI_OPS_SCRIPT" ]]; then
        log "WARN: notify helper not executable: ${NOTIFY_AWOOI_OPS_SCRIPT}"
        mark_cooldown
        return 0
    fi

    AWOOI_OPS_ALERTNAME="$alertname" \
    AWOOI_OPS_JOB_NAME="MOMO Pro health monitor" \
    AWOOI_OPS_STATUS="failed" \
    AWOOI_OPS_SEVERITY="warning" \
    AWOOI_OPS_SOURCE="momo-pro-health-monitor" \
    AWOOI_OPS_COMPONENT="momo-pro" \
    AWOOI_OPS_SUMMARY="$summary" \
    AWOOI_OPS_DETAIL="$detail" \
    "$NOTIFY_AWOOI_OPS_SCRIPT" >/dev/null 2>&1 || log "WARN: AWOOI ops notification failed"

    mark_cooldown
    log "ALERT_REPORTED: cooldown marked"
}

remote_health_code() {
    ssh -o ConnectTimeout=5 -o StrictHostKeyChecking="${SSH_STRICT_HOST_KEY_CHECKING}" "${REMOTE_USER}@${REMOTE_HOST}" \
        "curl -kLsS -o /dev/null -w '%{http_code}' --connect-timeout ${CURL_TIMEOUT} --max-time ${CURL_TIMEOUT} '${REMOTE_LOCAL_URL}' 2>/dev/null || echo 000" \
        2>/dev/null || echo "ssh_failed"
}

remote_container_status() {
    ssh -o ConnectTimeout=5 -o StrictHostKeyChecking="${SSH_STRICT_HOST_KEY_CHECKING}" "${REMOTE_USER}@${REMOTE_HOST}" \
        "docker inspect -f '{{.State.Status}} {{if .State.Health}}{{.State.Health.Status}}{{else}}no-healthcheck{{end}}' '${CONTAINER_NAME}' 2>/dev/null || echo missing" \
        2>/dev/null || echo "ssh_failed"
}

main() {
    log "CHECK: MOMO public health ${HEALTH_URL}"
    local public_code
    public_code=$(http_code_for "$HEALTH_URL")
    if is_success_code "$public_code"; then
        log "OK: public health ${public_code}; no alert"
        return 0
    fi

    log "WARN: public health ${public_code}; checking ${REMOTE_HOST} local app and container"
    local local_code container_status
    local_code=$(remote_health_code)
    container_status=$(remote_container_status)

    if is_success_code "$local_code"; then
        send_ops_alert \
            "MomoProPublicRouteUnhealthy" \
            "MOMO Pro public route unhealthy but 188 local app is OK" \
            "public=${HEALTH_URL} HTTP ${public_code}; local=${REMOTE_LOCAL_URL} HTTP ${local_code}; container=${CONTAINER_NAME} ${container_status}; likely gateway/proxy path; do not restart blindly."
    else
        send_ops_alert \
            "MomoProHealthFailed" \
            "MOMO Pro service health failed" \
            "public=${HEALTH_URL} HTTP ${public_code}; local=${REMOTE_LOCAL_URL} HTTP ${local_code}; container=${CONTAINER_NAME} ${container_status}; host=${REMOTE_HOST}; manual triage required."
    fi
    return 2
}

main "$@"
