#!/bin/bash
# =============================================================================
# admin-engine-bridge.sh -- Ghost + Vault + Phoenix Tool Bridge
# =============================================================================
# Category: ce | Bird: heron/hawk | Tier: 2 | Node-aware: yes
#
# Canonical entrypoint for C++ engine interactions. Wraps Vault (Delta)
# and Ghost (Alpha) HTTP APIs with idempotent execution.
#
# Actions:
#   --status            JSON pill (vault + ghost reachability)
#   --vault-status      Vault handler health
#   --vault-shards      Shard distribution status
#   --vault-store       Store artifact via Vault API
#   --vault-retrieve    Retrieve artifact
#   --ghost-status      Ghost engine pool status
#   --ghost-targets     Active shield targets
#   --ghost-rotate      Rotate domain to new shield
#   --send              Combined status check
#   --digest            Full report
#   --flush             Clear logs
#
# Port Registry (from SPEC.md):
#   8366 = s3rv1c3agent (ALL nodes, WireGuard)
#   8367 = Phoenix Orchestrator (Charlie)
#   8368 = Phoenix Executor (Alpha/Bravo/Charlie)
#   8369 = Ghost Bridge (Alpha)
#   8370 = Vault Handler (Delta)
# =============================================================================

TOOL_NAME="admin-engine-bridge"
TOOL_VERSION="3.0.0"
TOOL_TIER=2
TOOL_BIRD="heron"
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}"

# --- Canonical port assignments per SPEC.md ---
FLEET_ENV="/etc/binary/fleet.env"
[ -f "$FLEET_ENV" ] && source "$FLEET_ENV" 2>/dev/null

VAULT_HOST="${FLEET_DELTA_IP:-10.69.69.5}"
VAULT_PORT="8370"
VAULT_API="http://${VAULT_HOST}:${VAULT_PORT}"

GHOST_HOST="${FLEET_ALPHA_IP:-10.69.69.1}"
GHOST_PORT="8369"
GHOST_API="http://${GHOST_HOST}:${GHOST_PORT}"

PHOENIX_HOST="${FLEET_CHARLIE_IP:-10.69.69.4}"
PHOENIX_PORT="8367"
PHOENIX_API="http://${PHOENIX_HOST}:${PHOENIX_PORT}"

CURL_TIMEOUT="--connect-timeout 5 --max-time 15"

_api_get()  { curl -sf $CURL_TIMEOUT "$@" 2>/dev/null; }
_api_post() { curl -sf $CURL_TIMEOUT -X POST "$@" 2>/dev/null; }

# --- Vault ---
_do_vault_status() {
    echo "=== Vault Status ==="
    echo "  Endpoint: ${VAULT_API}"
    local resp; resp=$(_api_get "${VAULT_API}/health")
    if [ -n "$resp" ]; then
        echo "  Reachable: yes"
        echo "$resp" | python3 -m json.tool 2>/dev/null | sed 's/^/  /' || echo "  $resp"
    else echo "  Reachable: NO"; fi
}

_do_vault_shards() {
    echo "=== Vault Shards ==="
    local resp; resp=$(_api_get "${VAULT_API}/api/shards")
    if [ -n "$resp" ]; then
        echo "$resp" | python3 -m json.tool 2>/dev/null | sed 's/^/  /' || echo "  $resp"
    else echo "  Vault unreachable"; fi
}

vault_store() {
    local artifact_id="$1" file_path="$2" data_type="${3:-general}"
    [ -f "$file_path" ] || { log_error "File not found: $file_path"; return 1; }
    # Sanitize header values to prevent HTTP header injection
    artifact_id="${artifact_id//$'\n'/}"; artifact_id="${artifact_id//$'\r'/}"
    data_type="${data_type//$'\n'/}"; data_type="${data_type//$'\r'/}"
    local resp; resp=$(_api_post "${VAULT_API}/api/store" \
        -H "Content-Type: application/octet-stream" \
        -H "X-Artifact-ID: ${artifact_id}" \
        -H "X-Data-Type: ${data_type}" \
        --data-binary "@${file_path}")
    if [ -n "$resp" ]; then
        tool_audit "vault_store" "artifact=${artifact_id} node=${NODE_ID}"
        echo "OK: ${resp}"
    else log_error "Vault store failed: ${artifact_id}"; return 1; fi
}

vault_retrieve() {
    local artifact_id="$1" output_path="$2"
    local code; code=$(curl -sf $CURL_TIMEOUT -o "$output_path" -w "%{http_code}" \
        "${VAULT_API}/api/retrieve/${artifact_id}")
    if [ "$code" = "200" ]; then
        tool_audit "vault_retrieve" "artifact=${artifact_id} node=${NODE_ID}"
        echo "OK: $(stat -c%s "$output_path" 2>/dev/null || echo ?) bytes"
    else log_error "Vault retrieve failed: HTTP ${code}"; return 1; fi
}

# --- Ghost ---
_do_ghost_status() {
    echo "=== Ghost Status ==="
    echo "  Endpoint: ${GHOST_API}"
    local resp; resp=$(_api_get "${GHOST_API}/api/status")
    if [ -n "$resp" ]; then
        echo "  Reachable: yes"
        echo "$resp" | python3 -m json.tool 2>/dev/null | sed 's/^/  /' || echo "  $resp"
    else echo "  Reachable: NO"; fi
}

_do_ghost_targets() {
    echo "=== Ghost Targets ==="
    local resp; resp=$(_api_get "${GHOST_API}/api/targets")
    if [ -n "$resp" ]; then
        echo "$resp" | python3 -m json.tool 2>/dev/null | sed 's/^/  /' || echo "  $resp"
    else echo "  Ghost unreachable"; fi
}

ghost_rotate() {
    local domain="$1" reason="${2:-manual}"
    local j_domain j_reason
    j_domain="$(json_escape "$domain")"
    j_reason="$(json_escape "$reason")"
    local resp; resp=$(_api_post "${GHOST_API}/api/rotate" \
        -H "Content-Type: application/json" \
        -d "{\"domain\":\"${j_domain}\",\"reason\":\"${j_reason}\"}")
    if [ -n "$resp" ]; then
        tool_audit "ghost_rotate" "domain=${domain} reason=${reason} node=${NODE_ID}"
        echo "OK: ${resp}"
    else log_error "Ghost rotate failed: ${domain}"; return 1; fi
}

# --- Standard verbs ---
_do_send_impl() {
    echo "=== Tool Bridge: $(ts_local) ==="
    echo "  Node: ${NODE_ID}"
    echo ""
    _do_vault_status; echo ""
    _do_ghost_status; echo ""
    echo "--- Phoenix Orchestrator ---"
    echo "  Endpoint: ${PHOENIX_API}"
    local pr; pr=$(_api_get "${PHOENIX_API}/health")
    [ -n "$pr" ] && echo "  Reachable: yes" || echo "  Reachable: NO"
    tool_audit "send" "node=${NODE_ID}"
}

_do_status_impl() {
    local vault_up="false" ghost_up="false" phoenix_up="false"
    _api_get "${VAULT_API}/health" &>/dev/null && vault_up="true"
    _api_get "${GHOST_API}/api/status" &>/dev/null && ghost_up="true"
    _api_get "${PHOENIX_API}/health" &>/dev/null && phoenix_up="true"
    local s="healthy"
    [ "$vault_up" = "false" ] || [ "$ghost_up" = "false" ] && s="degraded"
    [ "$vault_up" = "false" ] && [ "$ghost_up" = "false" ] && s="down"
    echo "{\"tool\":\"${TOOL_NAME}\",\"node\":\"${NODE_ID}\",\"status\":\"${s}\",\"vault\":${vault_up},\"ghost\":${ghost_up},\"phoenix\":${phoenix_up},\"vault_api\":\"${VAULT_API}\",\"ghost_api\":\"${GHOST_API}\",\"phoenix_api\":\"${PHOENIX_API}\",\"checked_at\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}"
}

_do_digest_impl() { echo "=== Tool Report: ${NODE_ID} ==="; _do_send_impl; echo ""; _do_vault_shards; echo ""; _do_ghost_targets; }
_do_flush_impl() { [ -f "$TOOL_LOG" ] && truncate -s 0 "$TOOL_LOG"; echo "Flush complete"; }

tool_help() {
    echo "${TOOL_NAME} v${TOOL_VERSION} -- Ghost + Vault + Phoenix Tool Bridge"
    echo ""
    echo "Status:"
    echo "  --status            JSON pill"
    echo "  --vault-status      Vault handler health"
    echo "  --vault-shards      Shard distribution"
    echo "  --ghost-status      Ghost engine pool"
    echo "  --ghost-targets     Active shield targets"
    echo ""
    echo "Actions (veil-gated):"
    echo "  --vault-store <id> <file> [type]   Store artifact"
    echo "  --vault-retrieve <id> <outfile>    Retrieve artifact"
    echo "  --ghost-rotate <domain> [reason]   Rotate domain shield"
    echo ""
    echo "Standard: --send|--digest|--flush"
    echo ""
    echo "Ports: Vault=${VAULT_API} Ghost=${GHOST_API} Phoenix=${PHOENIX_API}"
}

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 "$@" ;;
    --vault-status)   _do_vault_status ;;
    --vault-shards)   _do_vault_shards ;;
    --vault-store)    shift; vault_store "$@" ;;
    --vault-retrieve) shift; vault_retrieve "$@" ;;
    --ghost-status)   _do_ghost_status ;;
    --ghost-targets)  _do_ghost_targets ;;
    --ghost-rotate)   shift; ghost_rotate "$@" ;;
    --help)           tool_help ;;
    *)                handle_standard_command "$@" ;;
esac
