#!/usr/bin/env bash
# site/health -- does the site actually answer, over both schemes?
set -o pipefail
SELF=$(readlink -f "${BASH_SOURCE[0]}")
NV_BASE=$(cd "$(dirname "$SELF")/../../.." && pwd)
export NV_BASE
# shellcheck source=/dev/null
. "$NV_BASE/lib/core/bootstrap.sh"

ui_header "$(t site_m_health)"

if [ $# -ge 1 ]; then domain=$1; else
    site_pick_domain "${1:-}" || exit $?
    domain=$SITE_DOMAIN
fi
nv_site_exists "$domain" || { ui_err "$(t site_not_registered)"; exit 2; }

# 000 with no explanation is useless: "the site is down" and "DNS does not point
# here yet" need completely different actions, so the curl exit code is mapped
# to a reason instead of being thrown away.
probe() {  # probe SCHEME -> "code reason"
    local out rc
    out=$(curl -sS -o /dev/null --max-time 10 -w '%{http_code}' "$1://$domain/" 2>/dev/null)
    rc=$?
    case $rc in
        0)  printf '%s ok' "${out:-000}" ;;
        6)  printf '000 %s' "$(t health_reason_dns)" ;;
        7)  printf '000 %s' "$(t health_reason_refused)" ;;
        28) printf '000 %s' "$(t health_reason_timeout)" ;;
        35|60) printf '000 %s' "$(t health_reason_tls)" ;;
        *)  printf '000 %s' "$(t health_reason_other "$rc")" ;;
    esac
}

http=$(probe http)
https=$(probe https)
code_h=${http%% *}; why_h=${http#* }
code_s=${https%% *}; why_s=${https#* }

ui_kv "$(t col_domain)" "$domain"
if [ "$code_h" = "000" ]; then
    ui_kv "http" "000  $why_h"
else
    ui_kv "http" "$code_h"
fi
if [ "$code_s" = "000" ]; then
    ui_kv "https" "${code_s}  $why_s"
else
    ui_kv "https" "$code_s"
fi

verdict() {
    case $1 in
        200|301|302|403) printf 'ok' ;;
        000) printf 'down' ;;
        *) printf 'error' ;;
    esac
}

h_state=$(verdict "$code_h")
s_state=$(verdict "$code_s")
ui_blank
[ "$h_state" = "ok" ] && ui_ok "$(t health_http_ok)" || ui_warn "$(t health_http_bad "$code_h")"
case "$(nv_site_get "$domain" ssl none)" in
    letsencrypt)
        [ "$s_state" = "ok" ] && ui_ok "$(t health_https_ok)" || ui_warn "$(t health_https_bad "$code_s")"
        ;;
    *) ui_info "$(t health_no_ssl)" ;;
esac

# TLS certificate seen by the client, not just the file on disk
if [ "$code_s" != "000" ]; then
    resp=$(curl -sS -I --max-time 10 "https://$domain/" 2>/dev/null | head -n 1)
    [ -n "$resp" ] && ui_kv "$(t health_response)" "$resp"
fi
ui_blank
exit 0
