#!/usr/bin/env bash
# mailcli — Hardened API client library (standalone version)
# Can be sourced or run directly for health checks
set -euo pipefail
shopt -s inherit_errexit 2>/dev/null || true

readonly NODE_ID="${NODE_ID:-$(hostname -s)}"
readonly ENGINE_IP="${ENGINE_IP:-127.0.0.1}"
readonly VAULT_KEY="${VAULT_KEY:-$(cat /dev/shm/vault.key 2>/dev/null | head -c 64 || printf '%s' 'INVALID-KEY-CHANGE-ME')}"
readonly ENGINE_URL="http://${ENGINE_IP}:8301"
readonly CLI_VERSION="4.0.0-hardened"

# ── Validation ─────────────────────────────────────────────────────────────
[[ "${NODE_ID}" =~ ^[a-zA-Z0-9_-]+$ ]] || { echo "Invalid NODE_ID" >&2; exit 1; }
[[ "${VAULT_KEY}" != "INVALID-KEY-CHANGE-ME" && "${#VAULT_KEY}" -ge 32 ]] || { echo "Invalid VAULT_KEY" >&2; exit 1; }

# ── HMAC Signing ───────────────────────────────────────────────────────────
se_hmac_sign() {
    local M="${1:-}" P="${2:-}" B="${3:-}"
    if [[ -z "${M}" || -z "${P}" ]]; then
        echo "se_hmac_sign: missing method or path" >&2
        return 1
    fi
    local TS NONCE PAYLOAD SIG
    TS="$(date -u +%s)"
    NONCE="$(openssl rand -hex 16)"
    PAYLOAD="${M}${P}${B}"
    SIG="$(printf '%s' "${TS}:${NONCE}:${PAYLOAD}" | openssl dgst -sha256 -hmac "${VAULT_KEY}" | awk '{print $NF}')"
    printf '%s\n%s\n%s\n' "${TS}" "${NONCE}" "${SIG}"
}

se_curl_get() {
    local P="${1:-}" TS NONCE SIG
    read -r TS NONCE SIG < <(se_hmac_sign "GET" "${P}" "") || return 1
    curl -sS --fail-with-body \
        --connect-timeout 5 -m 10 \
        "${ENGINE_URL}${P}" \
        -H "x-engine-ts: ${TS}" \
        -H "x-engine-nonce: ${NONCE}" \
        -H "x-engine-sig: ${SIG}" \
        -H "x-engine-node: ${NODE_ID}" \
        2>/dev/null || { echo "GET ${P} failed" >&2; return 1; }
}

se_curl_post() {
    local P="${1:-}" B="${2:-}" TS NONCE SIG
    read -r TS NONCE SIG < <(se_hmac_sign "POST" "${P}" "${B}") || return 1
    curl -sS --fail-with-body \
        --connect-timeout 5 -m 15 \
        -X POST "${ENGINE_URL}${P}" \
        -H "Content-Type: application/json" \
        -H "x-engine-ts: ${TS}" \
        -H "x-engine-nonce: ${NONCE}" \
        -H "x-engine-sig: ${SIG}" \
        -H "x-engine-node: ${NODE_ID}" \
        -d "${B}" \
        2>/dev/null || { echo "POST ${P} failed" >&2; return 1; }
}

se_curl_post_retry() {
    local P="${1:-}" B="${2:-}" DELAY=1 R=0 RESP=''
    for I in 1 2 3; do
        RESP="$(se_curl_post "${P}" "${B}" 2>/dev/null)" && { echo "${RESP}"; return 0; }
        sleep "${DELAY}"
        DELAY=$((DELAY * 2))
    done
    echo ''
    return 1
}

se_log() {
    local LVL="${1:-}" MSG="${2:-}"
    logger -t "se[${NODE_ID}]" -p "user.${LVL}" "${MSG}" 2>/dev/null || true
}

# ── Direct execution mode ──────────────────────────────────────────────────
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    case "${1:-}" in
        health)
            RESP="$(se_curl_get "/a/health" 2>/dev/null || printf '%s' '')"
            if [[ -n "${RESP}" ]]; then
                printf '%s\n' "${RESP}" | jq . 2>/dev/null || printf '%s\n' "${RESP}"
                exit 0
            else
                echo "FAIL: health check failed" >&2
                exit 1
            fi
            ;;
        version)
            printf 'mailcli v%s node=%s engine=%s\n' "${CLI_VERSION}" "${NODE_ID}" "${ENGINE_URL}"
            ;;
        *)
            printf 'Usage: %s health|version\n' "$0"
            exit 1
            ;;
    esac
fi

export NODE_ID ENGINE_URL VAULT_KEY
