#!/usr/bin/env bash
# =============================================================================
# /opt/binary/tools/s3rv1c3agent.sh -- hardened fleet orchestrator v6.0
# =============================================================================
# Canonical entrypoint for ALL tool execution.
# Post-consolidation: lean fleet of ~25 operational tools.
#
# Execution spine:
#   caller/phoenix/ghost/vault/cron
#     -> s3rv1c3agent -> policy classify -> veil (if write/sensitive/break-glass)
#     -> canonical tool -> verify -> DB log -> dashboard reads DB only
# =============================================================================

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=/dev/null
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 in ${SCRIPT_DIR} or parent" >&2
    exit 1
fi

TOOL_NAME="s3rv1c3agent"
TOOL_VERSION="6.0.0"
TOOL_LOG="/opt/binary/logs/tools/s3rv1c3agent.log"

# =============================================================================
# TOOL REGISTRY -- Only tools that physically exist as .sh files
# =============================================================================
declare -A TOOLS=(
    # --- Runtime (5) ---
    [runtime-health]="Health + Agent + Disk + Mining + Verify"
    [runtime-logs]="Log Manager + Error Scanner + Alerts + Cron"
    [runtime-services]="Service + Container + Cron + Self-Heal"
    [runtime-update]="Patch Orchestration (AlmaLinux 9)"
    [runtime-verify]="System Invariant Checker (pre-flight for Phoenix)"

    # --- Security (7) ---
    [security-detect]="Anomaly + Threat + Intrusion + Canary + fail2ban + CrowdSec"
    [security-response]="Lockdown + Rescue + Incident Response"
    [security-crypto]="Encryption + Key Management"
    [security-auth]="Auth + SSH Harden + Hop Guard + Sudo Audit"
    [security-password]="Password Rotation"
    [security-permissions]="Permissions Auditor"
    [security-audit]="Accounts + Keys + Sudoers + SUID + Fleet Audit"

    # --- Network (2) ---
    [network-status]="WireGuard + DNS + TLS + Ports + Connectivity"
    [network-control]="Firewall + Block/Unblock + SSH Harden"

    # --- Data (3) ---
    [data-backup]="Backup Creation + DB Dump + Rotation + Offsite"
    [data-integrity]="Backup Verify + Snapshot + DB Inventory"
    [data-restore]="Restore Manager (dangerous ops)"

    # --- Phoenix / Platform (3) ---
    [phoenix-core]="Phoenix AI Orchestrator"
    [admin-engine-bridge]="Ghost + Vault + Phoenix Tool Bridge"
    [admin-panel]="Panel Administration (files/config/db/email)"

    # --- Business (4) ---
    [admin-hosting]="Hosting Manager"
    [admin-email]="Email Manager"
    [admin-domains]="Domain + SSL Renewal + DNS Management"
    [admin-payments]="Payments"

    # --- Files (1) ---
    [admin-files]="File Integrity Manager"

    # --- Infrastructure (3) ---
    [veil]="Approval Layer"
    [365sign]="Tool Signing & Certification"
    [hello]="Session Layer"
)

# =============================================================================
# POLICY MAP -- Explicit classification overrides
# =============================================================================
declare -A POLICY_MAP=(
    # --- security-audit ---
    ["security-audit:--send"]="read"
    ["security-audit:--status"]="read"
    ["security-audit:--digest"]="read"
    ["security-audit:--flush"]="write"

    # --- security-response ---
    ["security-response:--lockdown"]="break-glass"
    ["security-response:--maintenance"]="sensitive"
    ["security-response:--rescue"]="break-glass"
    ["security-response:--clear-queue"]="break-glass"

    # --- security-crypto ---
    ["security-crypto:--encrypt"]="sensitive"
    ["security-crypto:--decrypt"]="sensitive"
    ["security-crypto:--rotate-key"]="sensitive"

    # --- security-auth ---
    ["security-auth:--rotate-ssh"]="sensitive"

    # --- security-password ---
    ["security-password:--send"]="sensitive"
    ["security-password:--status"]="read"
    ["security-password:--digest"]="read"

    # --- network-control ---
    ["network-control:--block"]="write"
    ["network-control:--unblock"]="write"
    ["network-control:--firewall-rule"]="write"
    ["network-control:--dns-failover"]="write"
    ["network-control:--ssh-harden"]="write"

    # --- data-restore ---
    ["data-restore:--send"]="sensitive"
    ["data-restore:--execute"]="break-glass"
    ["data-restore:--plan"]="read"
    ["data-restore:--status"]="read"

    # --- data-integrity ---
    ["data-integrity:--snapshot"]="write"

    # --- data-backup ---
    ["data-backup:--run-full"]="write"
    ["data-backup:--run-db"]="write"
    ["data-backup:--run-configs"]="write"
    ["data-backup:--run-keys"]="sensitive"
    ["data-backup:--rotate"]="write"
    ["data-backup:--offsite"]="write"

    # --- runtime-update ---
    ["runtime-update:--security"]="write"
    ["runtime-update:--full"]="sensitive"
    ["runtime-update:--rollback"]="break-glass"

    # --- runtime-services ---
    ["runtime-services:--containers restart"]="write"
    ["runtime-services:--containers prune"]="write"
    ["runtime-services:--self-heal"]="write"
    ["runtime-services:--prune-services"]="break-glass"

    # --- security-detect ---
    ["security-detect:--fail2ban unban"]="write"

    # --- veil ---
    ["veil:approve"]="sensitive"
    ["veil:deny"]="sensitive"
    ["veil:execute"]="sensitive"
    ["veil:clear-review"]="sensitive"
)

ALLOWED_SERVICE_CALLERS=(root snowdaddy service s3rv1c3-broker automation phoenix)
TOOL_CONFIG="/etc/binary/s3rv1c3agent.conf"
[ -f "$TOOL_CONFIG" ] && source "$TOOL_CONFIG" 2>/dev/null || true
readonly ALLOWED_SERVICE_CALLERS

# =============================================================================
# POLICY CLASSIFIER
# =============================================================================
classify_command() {
    local tool="$1"
    local cmd="${2:-help}"
    local key="${tool}:${cmd}"
    if [[ -n "${POLICY_MAP[$key]+x}" ]]; then
        printf '%s\n' "${POLICY_MAP[$key]}"
        return 0
    fi
    # Default classification by verb pattern
    case "$cmd" in
        help|--help|--status|--digest|status|list|show*|check*|verify*|watch|log|logs|tail|health|queue|result*|history|report|stats|search|findings|--backup-status|--db-inventory|--wireguard|--dns|--tls|--ports|--connectivity|--users|--sessions|--errors|--tail|--scan|--alerts|--cron|--heartbeat|--agent|--pill|--disk|--anomaly|--threat|--intrusion|--canary)
            printf 'read\n'
            ;;
        rotate*|restore*|get|export-env|bundle|init|--encrypt|--decrypt|--rotate*)
            printf 'sensitive\n'
            ;;
        execute|kill-switch|panic|full|security|deploy|rollback|--lockdown|--rescue|--clear-queue)
            printf 'break-glass\n'
            ;;
        *)
            printf 'write\n'
            ;;
    esac
}

redact_args_for_policy() {
    local policy="$1"; shift || true
    if [[ "$policy" = "sensitive" || "$policy" = "break-glass" ]]; then
        printf '[REDACTED_SENSITIVE_ARGS]'
    else
        printf '%s' "$*"
    fi
}

tool_script_for() {
    local tool="$1"
    printf '%s/%s.sh\n' "$SCRIPT_DIR" "$tool"
}

# =============================================================================
# UI
# =============================================================================
show_usage() {
    cat <<'EOF'
s3rv1c3agent <tool> <command> [args...]
s3rv1c3agent list
s3rv1c3agent --all <read-only-command>
s3rv1c3agent --all verify
s3rv1c3agent __classify <tool> <command>
s3rv1c3agent help
EOF
}

ctl_list() {
    echo "=== 365 Fleet Toolkit ==="
    printf "%-20s %s\n" "TOOL" "DESCRIPTION"
    printf "%-20s %s\n" "--------------------" "--------------------------------------------"
    local tool
    for tool in $(printf '%s\n' "${!TOOLS[@]}" | sort); do
        printf "%-20s %s\n" "$tool" "${TOOLS[$tool]}"
    done
    echo ""
    echo "Total: ${#TOOLS[@]} tools"
}

is_allowed_service_caller() {
    local caller="$1" allowed
    for allowed in "${ALLOWED_SERVICE_CALLERS[@]}"; do
        [[ "$caller" = "$allowed" ]] && return 0
    done
    return 1
}

require_valid_session_if_needed() {
    local caller="$1" policy="$2"
    case "$caller" in
        automation|s3rv1c3-broker|service)
            require_active_session || die "${caller} requires active hello session"
            ;;
        phoenix)
            if [[ "$policy" != "read" ]]; then
                : # intercepted to veil later
            fi
            ;;
        *)
            ;;
    esac
}

tool_exists_and_executable() {
    local tool_target="$1" tool_script
    tool_script="$(tool_script_for "$tool_target")"
    [[ -f "$tool_script" ]] || die "Tool script missing: ${tool_target}.sh"
    [[ -x "$tool_script" ]] || { log_error "Tool script not executable: $tool_script"; return 1; }
    printf '%s\n' "$tool_script"
}

dispatch_audit() {
    local event="$1" caller="$2" session_id="$3" tool_target="$4" cmd_verb="$5" policy="$6" result="${7:-attempt}"
    tool_audit "$event" "caller=${caller} session_id=${session_id:-none} tool=${tool_target} verb=${cmd_verb} policy=${policy} result=${result}"
}

ctl_all() {
    local cmd="${1:-status}" tool policy
    for tool in $(printf '%s\n' "${!TOOLS[@]}" | sort); do
        [[ "$tool" =~ ^(s3rv1c3agent|common|veil|hello|365sign)$ ]] && continue
        policy="$(classify_command "$tool" "$cmd")"
        [[ "$policy" = "read" ]] || continue
        echo "--- ${tool} ${cmd} ---"
        bash "${SCRIPT_DIR}/admin-control.sh" "$tool" "$cmd" 2>&1 | head -20 || true
    done
}

ctl_verify_all() {
    local pass=0 fail=0 tool
    for tool in $(printf '%s\n' "${!TOOLS[@]}" | sort); do
        [[ "$tool" =~ ^(common|s3rv1c3agent|veil|hello|365sign)$ ]] && continue
        if bash "${SCRIPT_DIR}/admin-control.sh" "$tool" verify >/dev/null 2>&1; then
            pass=$((pass + 1))
        else
            fail=$((fail + 1))
            echo "FAIL: ${tool}"
        fi
    done
    echo "Passed=${pass} Failed=${fail}"
}

# =============================================================================
# MAIN
# =============================================================================
main() {
    tool_init

    case "${1:-help}" in
        __classify) shift; classify_command "${1:-}" "${2:-help}"; return 0 ;;
        list) ctl_list; return 0 ;;
        --all)
            shift
            if [[ "${1:-status}" = "verify" ]]; then ctl_verify_all; else ctl_all "$@"; fi
            return 0
            ;;
        help|--help|-h) show_usage; return 0 ;;
    esac

    local tool_target="${1:-}" caller session_id cmd_verb policy safe_args tool_script
    shift || true

    validate_name "$tool_target" "tool" || exit 1
    [[ -n "${TOOLS[$tool_target]+x}" ]] || die "Unknown tool: ${tool_target}"

    caller="$(whoami)"
    session_id="${HELLO_SESSION_ID:-}"
    cmd_verb="${1:-help}"
    policy="$(classify_command "$tool_target" "$cmd_verb")"
    safe_args="$(redact_args_for_policy "$policy" "$*")"
    tool_script="$(tool_exists_and_executable "$tool_target")"

    is_allowed_service_caller "$caller" || die "Access denied for caller '${caller}'"
    require_valid_session_if_needed "$caller" "$policy"

    dispatch_audit "dispatch" "$caller" "$session_id" "$tool_target" "$cmd_verb" "$policy" "attempt"

    case "$caller" in
        root|snowdaddy)
            [[ "$policy" = "break-glass" ]] && dispatch_audit "break_glass" "$caller" "$session_id" "$tool_target" "$cmd_verb" "$policy" "allowed"
            exec bash "$tool_script" "$@"
            ;;
        automation|s3rv1c3-broker|service)
            if [[ "$policy" = "break-glass" || "$policy" = "sensitive" ]]; then
                dispatch_audit "veil_intercept" "$caller" "$session_id" "$tool_target" "$cmd_verb" "$policy" "queued"
                exec bash "${SCRIPT_DIR}/veil.sh" "$tool_target" "$cmd_verb" "$@"
            fi
            exec bash "$tool_script" "$@"
            ;;
        phoenix)
            if [[ "$policy" = "read" ]]; then
                exec bash "$tool_script" "$@"
            fi
            dispatch_audit "veil_intercept" "$caller" "$session_id" "$tool_target" "$cmd_verb" "$policy" "queued"
            exec bash "${SCRIPT_DIR}/veil.sh" "$tool_target" "$cmd_verb" "$@"
            ;;
        *)
            dispatch_audit "access_denied" "$caller" "$session_id" "$tool_target" "$cmd_verb" "$policy" "denied"
            die "Access denied for caller '${caller}'"
            ;;
    esac
}

main "$@"
