#!/usr/bin/env bash
# ==============================================================================
# Logxal Universal VPS Health & Security Audit Engine
#
# Dual-Mode Execution:
#   1. Interactive TTY Mode (Marketing CLI):
#      curl -sSL https://logxal.com/audit | bash
#      Prompts user for Option 1 (Full Health) or Option 2 (Security Only),
#      renders animated progress, formatted report, and Logxal Autonomous SRE banner.
#
#   2. Headless Agent Mode:
#      audit.sh --security-only --json
#      Outputs clean, structured JSON to stdout with no prompts or marketing.
#
# 100% POSIX / Bash compatible (Ubuntu, Debian, RHEL, CentOS, Rocky, Alma, Alpine, Arch).
# Zero external dependencies required (no jq, bc, netstat).
# 100% Read-Only: Makes zero changes to system files or network rules.
# ==============================================================================

set -u

# --- Flag Parsing ---
MODE_SECURITY_ONLY=false
MODE_JSON=false
MODE_QUIET=false

for arg in "$@"; do
    case "$arg" in
        --security-only)
            MODE_SECURITY_ONLY=true
            ;;
        --json)
            MODE_JSON=true
            ;;
        --quiet|-q)
            MODE_QUIET=true
            ;;
        --help|-h)
            echo "Usage: audit.sh [OPTIONS]"
            echo "  --security-only    Run only security & vulnerability checks"
            echo "  --json             Output results in structured JSON format"
            echo "  --quiet, -q        Suppress interactive prompts and spinners"
            exit 0
            ;;
    esac
done

# Detect interactive terminal
IS_TTY=false
if [ -t 0 ] && [ -t 1 ] && [ "$MODE_JSON" = false ] && [ "$MODE_QUIET" = false ]; then
    IS_TTY=true
fi

# Colors
if [ "$IS_TTY" = true ]; then
    C_RESET="\033[0m"
    C_BOLD="\033[1m"
    C_DIM="\033[2m"
    C_RED="\033[1;31m"
    C_GREEN="\033[1;32m"
    C_YELLOW="\033[1;33m"
    C_BLUE="\033[1;34m"
    C_CYAN="\033[1;36m"
    C_MAGENTA="\033[1;35m"
    C_WHITE="\033[1;37m"
    C_BG_BLUE="\033[44m\033[37m"
else
    C_RESET=""
    C_BOLD=""
    C_DIM=""
    C_RED=""
    C_GREEN=""
    C_YELLOW=""
    C_BLUE=""
    C_CYAN=""
    C_MAGENTA=""
    C_WHITE=""
    C_BG_BLUE=""
fi

# ==============================================================================
# Helper Functions
# ==============================================================================

log_step() {
    if [ "$IS_TTY" = true ]; then
        echo -e " ${C_CYAN}➜${C_RESET} ${C_BOLD}$1${C_RESET}"
    fi
}

log_sub() {
    if [ "$IS_TTY" = true ]; then
        echo -e "   ${C_DIM}• $1${C_RESET}"
    fi
}

has_cmd() {
    command -v "$1" >/dev/null 2>&1
}

# ==============================================================================
# Interactive Welcome & Option Prompt (TTY Mode Only)
# ==============================================================================

AUDIT_CHOICE="1"

if [ "$IS_TTY" = true ]; then
    clear 2>/dev/null || true
    echo -e "${C_CYAN}"
    echo "  _       ____   ______  _  __    _      "
    echo " | |     / __ \ / ____/ | |/ /   / \     |  Logxal Universal VPS Audit Engine"
    echo " | |    | /  | | | __   |   /   / _ \    |  Version: 2.4.0 (Read-Only)"
    echo " | |___ | \__| | |_\ \  |   \  / ___ \   |  Operating System Inspection"
    echo " |_____| \____/ \____/  |_|\_\/_/   \_\  |"
    echo -e "${C_RESET}"
    echo -e " ${C_BOLD}Welcome!${C_RESET} This tool inspects your server health and security posture."
    echo -e " It is ${C_GREEN}100% read-only${C_RESET} and makes ${C_BOLD}zero changes${C_RESET} to your server."
    echo ""
    echo -e " Please choose what you would like to audit:"
    echo ""
    echo -e "   ${C_BOLD}${C_CYAN}[1] Complete Health & Performance Checkup${C_RESET}"
    echo -e "       ${C_DIM}Full inspection — running services, CPU/RAM/Disk health, background${C_RESET}"
    echo -e "       ${C_DIM}processes, listening ports, and security posture. (~20-40s)${C_RESET}"
    echo ""
    echo -e "   ${C_BOLD}${C_CYAN}[2] Fast Security & Vulnerability Check${C_RESET}"
    echo -e "       ${C_DIM}Focused scan — open ports, database exposure, firewall holes, SSH${C_RESET}"
    echo -e "       ${C_DIM}configuration, and brute-force bot risks. (~10-15s)${C_RESET}"
    echo ""
    read -r -p " Enter your choice [1 or 2] (Default: 1): " USER_INPUT_CHOICE || USER_INPUT_CHOICE="1"
    
    if [ "$USER_INPUT_CHOICE" = "2" ]; then
        AUDIT_CHOICE="2"
        MODE_SECURITY_ONLY=true
    else
        AUDIT_CHOICE="1"
    fi
    echo ""
fi

# ==============================================================================
# AUDIT INSPECTION ROUTINES
# ==============================================================================

# Data variables
OS_NAME="Unknown Linux"
OS_VERSION=""
OS_ARCH="$(uname -m 2>/dev/null || echo 'unknown')"
KERNEL_VERSION="$(uname -r 2>/dev/null || echo 'unknown')"
CPU_CORES=1
CPU_LOAD_1M="0.00"
TOTAL_RAM_MB=0
USED_RAM_MB=0
RAM_PERCENT=0
TOTAL_SWAP_MB=0
USED_SWAP_MB=0
SWAP_PERCENT=0
DISK_TOTAL_GB=0
DISK_USED_GB=0
DISK_PERCENT=0
INODE_PERCENT=0
UPTIME_DAYS=0

# Security Findings (Arrays / Lists)
FINDINGS_JSON="[]"
SCORE=100
SCORE_STATUS="clean"

# 1. Distro & OS Detection
if [ -f /etc/os-release ]; then
    # shellcheck disable=SC1091
    . /etc/os-release
    OS_NAME="${NAME:-Linux}"
    OS_VERSION="${VERSION_ID:-}"
elif [ -f /etc/redhat-release ]; then
    OS_NAME="$(cat /etc/redhat-release)"
fi

# 2. CPU & Load
if [ -f /proc/cpuinfo ]; then
    CPU_CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 1)
fi
if [ -f /proc/loadavg ]; then
    CPU_LOAD_1M=$(awk '{print $1}' /proc/loadavg 2>/dev/null || echo "0.00")
fi

# 3. Memory & Swap
if [ -f /proc/meminfo ]; then
    MEM_TOTAL_KB=$(grep MemTotal /proc/meminfo | awk '{print $2}' || echo 0)
    MEM_AVAIL_KB=$(grep MemAvailable /proc/meminfo | awk '{print $2}' || echo 0)
    TOTAL_RAM_MB=$((MEM_TOTAL_KB / 1024))
    if [ "$TOTAL_RAM_MB" -gt 0 ] && [ "$MEM_AVAIL_KB" -gt 0 ]; then
        USED_RAM_MB=$(((MEM_TOTAL_KB - MEM_AVAIL_KB) / 1024))
        RAM_PERCENT=$(((USED_RAM_MB * 100) / TOTAL_RAM_MB))
    fi

    SWAP_TOTAL_KB=$(grep SwapTotal /proc/meminfo | awk '{print $2}' || echo 0)
    SWAP_FREE_KB=$(grep SwapFree /proc/meminfo | awk '{print $2}' || echo 0)
    TOTAL_SWAP_MB=$((SWAP_TOTAL_KB / 1024))
    if [ "$TOTAL_SWAP_MB" -gt 0 ]; then
        USED_SWAP_MB=$(((SWAP_TOTAL_KB - SWAP_FREE_KB) / 1024))
        SWAP_PERCENT=$(((USED_SWAP_MB * 100) / TOTAL_SWAP_MB))
    fi
fi

# 4. Storage
if has_cmd df; then
    DISK_INFO=$(df -P / 2>/dev/null | tail -n 1)
    if [ -n "$DISK_INFO" ]; then
        DISK_TOTAL_KB=$(echo "$DISK_INFO" | awk '{print $2}')
        DISK_USED_KB=$(echo "$DISK_INFO" | awk '{print $3}')
        DISK_PERCENT=$(echo "$DISK_INFO" | awk '{gsub(/%/,"",$5); print $5}')
        if [ -n "$DISK_PERCENT" ] && [ "$DISK_PERCENT" -ge 0 ] 2>/dev/null; then
            :
        else
            DISK_PERCENT=0
        fi
        if [ -n "$DISK_TOTAL_KB" ] && [ "$DISK_TOTAL_KB" -gt 0 ] 2>/dev/null; then
            DISK_TOTAL_GB=$((DISK_TOTAL_KB / 1048576))
            DISK_USED_GB=$((DISK_USED_KB / 1048576))
        fi
    fi
    INODE_PERCENT=$(df -Pi / 2>/dev/null | tail -n 1 | awk '{gsub(/%/,"",$5); print $5}' || echo 0)
    if [ -z "$INODE_PERCENT" ] || ! [ "$INODE_PERCENT" -ge 0 ] 2>/dev/null; then
        INODE_PERCENT=0
    fi
fi

# 5. Uptime
if [ -f /proc/uptime ]; then
    UPTIME_SECS=$(awk '{print int($1)}' /proc/uptime 2>/dev/null || echo 0)
    UPTIME_DAYS=$((UPTIME_SECS / 86400))
fi

# Storage for Findings (Structured for JSON and Display)
FINDING_IDS=()
FINDING_SEVERITIES=()
FINDING_TITLES=()
FINDING_DESCRIPTIONS=()
FINDING_CATEGORIES=()

add_finding() {
    local fid="$1"
    local fsev="$2"
    local fcat="$3"
    local ftitle="$4"
    local fdesc="$5"
    local fpenalty="$6"

    FINDING_IDS+=("$fid")
    FINDING_SEVERITIES+=("$fsev")
    FINDING_CATEGORIES+=("$fcat")
    FINDING_TITLES+=("$ftitle")
    FINDING_DESCRIPTIONS+=("$fdesc")

    SCORE=$((SCORE - fpenalty))
    if [ "$SCORE" -lt 0 ]; then
        SCORE=0
    fi
}

# ==============================================================================
# Security Inspection Logic
# ==============================================================================

log_step "Auditing Network Sockets & Exposed Databases..."

# Check Listening Ports (using ss, netstat, or /proc/net/tcp)
EXPOSED_PORTS=()
DETECTED_SSH_PORT="22"

if has_cmd ss; then
    SOCKET_OUTPUT=$(ss -tulpn 2>/dev/null || true)
elif has_cmd netstat; then
    SOCKET_OUTPUT=$(netstat -tulpn 2>/dev/null || true)
else
    SOCKET_OUTPUT=""
fi

# Determine active SSH Port
SSH_FOUND_PORT=$(echo "$SOCKET_OUTPUT" | grep -E 'sshd|ssh' | awk '{for(i=1;i<=NF;i++) if($i ~ /:[0-9]+$/) {print $i; break}}' | awk -F':' '{print $NF}' | head -n 1 || echo "")
if [ -z "$SSH_FOUND_PORT" ] || ! [ "$SSH_FOUND_PORT" -gt 0 ] 2>/dev/null; then
    if has_cmd sshd; then
        SSH_FOUND_PORT=$(sshd -T -C user=root 2>/dev/null | grep -i '^port ' | awk '{print $2}' | head -n 1 || echo "")
    fi
fi
if [ -z "$SSH_FOUND_PORT" ] || ! [ "$SSH_FOUND_PORT" -gt 0 ] 2>/dev/null; then
    SSH_FOUND_PORT=$(grep -Eih '^\s*Port\s+[0-9]+' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf 2>/dev/null | awk '{print $2}' | tail -n 1 || echo "")
fi
if [ -n "$SSH_FOUND_PORT" ] && [ "$SSH_FOUND_PORT" -gt 0 ] 2>/dev/null; then
    DETECTED_SSH_PORT="$SSH_FOUND_PORT"
fi

# Check for Dangerous Database Bindings on 0.0.0.0 or [::]
check_exposed_port() {
    local port="$1"
    local name="$2"
    if echo "$SOCKET_OUTPUT" | grep -E "(0\.0\.0\.0|::|:::):${port}\b" >/dev/null 2>&1; then
        EXPOSED_PORTS+=("$port ($name)")
        add_finding \
            "exposed_${port}" \
            "critical" \
            "database" \
            "${name} (Port ${port}) exposed to the public internet" \
            "The service is listening on 0.0.0.0 or [::], allowing external port scanners and attackers direct access." \
            15
    fi
}

check_exposed_port "5432" "PostgreSQL"
check_exposed_port "3306" "MySQL/MariaDB"
check_exposed_port "6379" "Redis"
check_exposed_port "27017" "MongoDB"
check_exposed_port "9200" "Elasticsearch"
check_exposed_port "2375" "Docker Daemon (Unencrypted)"

# Firewall Status Inspection
log_step "Inspecting Firewall (UFW / Firewalld / iptables)..."
FIREWALL_ACTIVE=false
FIREWALL_TYPE="none"

if has_cmd ufw; then
    UFW_STATUS=$(ufw status 2>/dev/null || true)
    if echo "$UFW_STATUS" | grep -iq "status: active"; then
        FIREWALL_ACTIVE=true
        FIREWALL_TYPE="ufw"
    fi
elif has_cmd firewall-cmd; then
    if firewall-cmd --state >/dev/null 2>&1; then
        FIREWALL_ACTIVE=true
        FIREWALL_TYPE="firewalld"
    fi
elif has_cmd iptables; then
    # Check if any non-empty filter rules exist
    IPT_RULES=$(iptables -L INPUT -n 2>/dev/null | grep -E 'ACCEPT|DROP|REJECT' | wc -l || echo 0)
    if [ "$IPT_RULES" -gt 2 ]; then
        FIREWALL_ACTIVE=true
        FIREWALL_TYPE="iptables"
    fi
fi

if [ "$FIREWALL_ACTIVE" = false ]; then
    add_finding \
        "firewall_inactive" \
        "critical" \
        "firewall" \
        "Firewall is inactive or unconfigured" \
        "No active packet filtering detected. All non-firewalled ports are directly accessible from the public internet." \
        20
fi

# SSH Hardening Inspection
log_step "Checking SSH Configuration Hardening..."
SSH_PASSWORD_AUTH="yes"
SSH_ROOT_LOGIN="yes"

SSHD_CONFIG_FILE="/etc/ssh/sshd_config"
if has_cmd sshd; then
    PW_SETTING=$(sshd -T -C user=root 2>/dev/null | grep -i '^passwordauthentication ' | awk '{print tolower($2)}' || echo "")
    ROOT_SETTING=$(sshd -T -C user=root 2>/dev/null | grep -i '^permitrootlogin ' | awk '{print tolower($2)}' || echo "")
fi

if [ -z "${PW_SETTING:-}" ] && [ -f "$SSHD_CONFIG_FILE" ]; then
    PW_SETTING=$(grep -Eih '^\s*PasswordAuthentication\s+' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf 2>/dev/null | tail -n 1 | awk '{print tolower($2)}' || echo "")
fi
if [ "${PW_SETTING:-}" = "no" ]; then
    SSH_PASSWORD_AUTH="no"
fi

if [ -z "${ROOT_SETTING:-}" ] && [ -f "$SSHD_CONFIG_FILE" ]; then
    ROOT_SETTING=$(grep -Eih '^\s*PermitRootLogin\s+' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf 2>/dev/null | tail -n 1 | awk '{print tolower($2)}' || echo "")
fi
if [ "${ROOT_SETTING:-}" = "no" ] || [ "${ROOT_SETTING:-}" = "prohibit-password" ]; then
    SSH_ROOT_LOGIN="${ROOT_SETTING}"
fi

if [ "$SSH_PASSWORD_AUTH" = "yes" ]; then
    add_finding \
        "ssh_password_auth" \
        "warning" \
        "ssh" \
        "SSH password authentication is enabled" \
        "Password authentication leaves the SSH daemon vulnerable to brute-force credential stuffing. Key-based authentication is strongly recommended." \
        10
fi

if [ "$SSH_ROOT_LOGIN" = "yes" ]; then
    add_finding \
        "ssh_root_login" \
        "warning" \
        "ssh" \
        "Direct root login via SSH is allowed" \
        "Automated attack bots target the 'root' user directly. Setting PermitRootLogin to 'prohibit-password' or 'no' prevents brute force." \
        10
fi

# Swap Allocation Inspection
log_step "Checking Memory Safety & Swap Allocation..."
if [ "$TOTAL_SWAP_MB" -eq 0 ]; then
    add_finding \
        "zero_swap" \
        "warning" \
        "memory" \
        "0 MB Swap space configured" \
        "The server has no swap partition or file. Any sudden RAM spike will trigger the Linux kernel OOM-killer, abruptly terminating databases and critical apps." \
        15
fi

# Intrusion Defense (fail2ban) & Bot Log Analysis
log_step "Analyzing Brute-Force Bot Activity & Intrusion Defense..."
FAIL2BAN_ACTIVE=false
if has_cmd fail2ban-client; then
    if fail2ban-client ping >/dev/null 2>&1; then
        FAIL2BAN_ACTIVE=true
    fi
elif systemctl is-active --quiet fail2ban 2>/dev/null; then
    FAIL2BAN_ACTIVE=true
fi

FAILED_LOGIN_COUNT=0
if [ -f /var/log/auth.log ]; then
    FAILED_LOGIN_COUNT=$(grep -ci "Failed password" /var/log/auth.log 2>/dev/null || echo 0)
elif [ -f /var/log/secure ]; then
    FAILED_LOGIN_COUNT=$(grep -ci "Failed password" /var/log/secure 2>/dev/null || echo 0)
elif has_cmd journalctl; then
    FAILED_LOGIN_COUNT=$(journalctl -u ssh -u sshd -u 'ssh@*' --since "24 hours ago" 2>/dev/null | grep -ci "Failed password" || echo 0)
fi

if [ "$FAIL2BAN_ACTIVE" = false ]; then
    DESC_MSG="No automated intrusion defense active."
    if [ "$FAILED_LOGIN_COUNT" -gt 10 ]; then
        DESC_MSG="Detected ${FAILED_LOGIN_COUNT} failed bot login attempts in recent logs with no active ban jail."
    fi
    add_finding \
        "fail2ban_missing" \
        "warning" \
        "intrusion" \
        "No automated brute-force protection (fail2ban inactive)" \
        "$DESC_MSG" \
        10
fi

# Package Updates & Pending Reboot
PENDING_SECURITY_UPDATES=0
if [ -f /usr/lib/update-notifier/apt-check ]; then
    PKG_STATUS=$(/usr/lib/update-notifier/apt-check 2>/dev/null || echo "0;0")
    PENDING_SECURITY_UPDATES=$(echo "$PKG_STATUS" | cut -d';' -f2 || echo 0)
fi

if [ "$PENDING_SECURITY_UPDATES" -gt 0 ]; then
    add_finding \
        "security_updates_pending" \
        "info" \
        "updates" \
        "${PENDING_SECURITY_UPDATES} security package updates pending" \
        "Unapplied OS patches leave known CVE vulnerabilities unmitigated." \
        5
fi

# ==============================================================================
# Full Health Inspection (Option 1 Only)
# ==============================================================================

FAILED_UNITS_COUNT=0
ZOMBIE_PROCS=0

if [ "$MODE_SECURITY_ONLY" = false ]; then
    log_step "Auditing Running Services, Zombie Processes & Performance..."

    # Check for failed systemd units
    if has_cmd systemctl; then
        FAILED_UNITS_COUNT=$(systemctl --failed --no-legend 2>/dev/null | grep -E '\S' | wc -l | tr -d ' ' || echo 0)
        if [ -n "$FAILED_UNITS_COUNT" ] && [ "$FAILED_UNITS_COUNT" -gt 0 ] 2>/dev/null; then
            add_finding \
                "failed_systemd_units" \
                "warning" \
                "services" \
                "${FAILED_UNITS_COUNT} system service(s) currently in failed state" \
                "One or more systemd background services crashed or failed to start." \
                5
        fi
    fi

    # Check for zombie processes
    if has_cmd ps; then
        ZOMBIE_PROCS=$(ps -eo stat 2>/dev/null | grep -E '^Z' | wc -l | tr -d ' ' || echo 0)
        if [ -n "$ZOMBIE_PROCS" ] && [ "$ZOMBIE_PROCS" -gt 0 ] 2>/dev/null; then
            add_finding \
                "zombie_processes" \
                "info" \
                "processes" \
                "${ZOMBIE_PROCS} defunct/zombie process(es) detected" \
                "Parent processes exited without reaping child exit codes." \
                5
        fi
    fi

    # Disk usage warning
    if [ -n "$DISK_PERCENT" ] && [ "$DISK_PERCENT" -gt 85 ] 2>/dev/null; then
        add_finding \
            "disk_near_full" \
            "critical" \
            "storage" \
            "Root filesystem is ${DISK_PERCENT}% full" \
            "High disk usage may lead to write failures, log truncation, and crashed services." \
            15
    fi
fi

# Final Score Status
if [ "$SCORE" -ge 90 ]; then
    SCORE_STATUS="clean"
elif [ "$SCORE" -ge 60 ]; then
    SCORE_STATUS="needs_attention"
else
    SCORE_STATUS="critical"
fi

# ==============================================================================
# Generate Planned Hardening Actions
# ==============================================================================

PLAN_TITLES=()
PLAN_DETAILS=()
PLAN_ACTIONS=()

if [ "$FIREWALL_ACTIVE" = false ]; then
    PLAN_TITLES+=("Enable UFW Firewall & Whitelist Ports")
    PLAN_DETAILS+=("Sets default deny incoming, whitelists active SSH port ${DETECTED_SSH_PORT}, HTTP (80), and HTTPS (443).")
    PLAN_ACTIONS+=("enable_ufw")
fi

if [ ${#EXPOSED_PORTS[@]} -gt 0 ]; then
    PLAN_TITLES+=("Isolate Exposed Internal Databases")
    PLAN_DETAILS+=("Restricts external access to ports (${EXPOSED_PORTS[*]}) so only local apps can connect.")
    PLAN_ACTIONS+=("isolate_db_ports")
fi

if [ "$FAIL2BAN_ACTIVE" = false ]; then
    PLAN_TITLES+=("Install & Enable fail2ban Brute-Force Protection")
    PLAN_DETAILS+=("Installs fail2ban with default sshd jail to automatically ban malicious bot IPs.")
    PLAN_ACTIONS+=("install_fail2ban")
fi

if [ "$TOTAL_SWAP_MB" -eq 0 ]; then
    PLAN_TITLES+=("Allocate 2.0 GB Emergency Swapfile")
    PLAN_DETAILS+=("Creates and mounts a protected 2GB /swapfile to prevent sudden out-of-memory kernel crashes.")
    PLAN_ACTIONS+=("create_swap")
fi

UNATTENDED_ACTIVE=false
if systemctl is-active --quiet unattended-upgrades 2>/dev/null || systemctl is-active --quiet dnf-automatic.timer 2>/dev/null; then
    UNATTENDED_ACTIVE=true
fi

if [ "$UNATTENDED_ACTIVE" = false ] && ([ "$PENDING_SECURITY_UPDATES" -gt 0 ] || has_cmd apt-get || has_cmd dnf); then
    PLAN_TITLES+=("Enable Automated Security Updates")
    PLAN_DETAILS+=("Installs and enables unattended-upgrades so critical Linux security patches apply automatically.")
    PLAN_ACTIONS+=("enable_unattended_upgrades")
fi

# ==============================================================================
# OUTPUT GENERATION: JSON MODE
# ==============================================================================

if [ "$MODE_JSON" = true ]; then
    # Manual JSON generator (zero external jq dependency)
    printf '{\n'
    printf '  "audit_version": "2.4.0",\n'
    printf '  "timestamp": "%s",\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
    printf '  "security_score": %d,\n' "$SCORE"
    printf '  "status": "%s",\n' "$SCORE_STATUS"
    printf '  "system_info": {\n'
    printf '    "os_name": "%s",\n' "$OS_NAME"
    printf '    "os_version": "%s",\n' "$OS_VERSION"
    printf '    "arch": "%s",\n' "$OS_ARCH"
    printf '    "kernel": "%s",\n' "$KERNEL_VERSION"
    printf '    "uptime_days": %d,\n' "$UPTIME_DAYS"
    printf '    "cpu_cores": %d,\n' "$CPU_CORES"
    printf '    "cpu_load_1m": "%s",\n' "$CPU_LOAD_1M"
    printf '    "total_ram_mb": %d,\n' "$TOTAL_RAM_MB"
    printf '    "used_ram_mb": %d,\n' "$USED_RAM_MB"
    printf '    "ram_pct": %d,\n' "$RAM_PERCENT"
    printf '    "total_swap_mb": %d,\n' "$TOTAL_SWAP_MB"
    printf '    "used_swap_mb": %d,\n' "$USED_SWAP_MB"
    printf '    "disk_total_gb": %d,\n' "$DISK_TOTAL_GB"
    printf '    "disk_used_gb": %d,\n' "$DISK_USED_GB"
    printf '    "disk_pct": %d,\n' "$DISK_PERCENT"
    printf '    "ssh_port": %d,\n' "$DETECTED_SSH_PORT"
    printf '    "firewall_active": %s,\n' "$FIREWALL_ACTIVE"
    printf '    "firewall_type": "%s",\n' "$FIREWALL_TYPE"
    printf '    "fail2ban_active": %s\n' "$FAIL2BAN_ACTIVE"
    printf '  },\n'

    # Findings Array
    printf '  "findings": ['
    for i in "${!FINDING_IDS[@]}"; do
        if [ "$i" -gt 0 ]; then printf ','; fi
        printf '\n    {\n'
        printf '      "id": "%s",\n' "${FINDING_IDS[$i]}"
        printf '      "severity": "%s",\n' "${FINDING_SEVERITIES[$i]}"
        printf '      "category": "%s",\n' "${FINDING_CATEGORIES[$i]}"
        printf '      "title": "%s",\n' "${FINDING_TITLES[$i]}"
        if [ "${FINDING_IDS[$i]}" = "firewall_inactive" ] || [ "${FINDING_CATEGORIES[$i]}" = "ssh" ]; then
            printf '      "ssh_port": %d,\n' "$DETECTED_SSH_PORT"
        fi
        # Escape quotes in description
        DESC_ESCAPED=$(echo "${FINDING_DESCRIPTIONS[$i]}" | sed 's/"/\\"/g')
        printf '      "description": "%s"\n' "$DESC_ESCAPED"
        printf '    }'
    done
    printf '\n  ],\n'

    # Hardening Plan Array
    printf '  "hardening_plan": ['
    for j in "${!PLAN_TITLES[@]}"; do
        if [ "$j" -gt 0 ]; then printf ','; fi
        printf '\n    {\n'
        printf '      "action": "%s",\n' "${PLAN_ACTIONS[$j]}"
        printf '      "title": "%s",\n' "${PLAN_TITLES[$j]}"
        printf '      "detail": "%s",\n' "${PLAN_DETAILS[$j]}"
        printf '      "ssh_port": %d\n' "$DETECTED_SSH_PORT"
        printf '    }'
    done
    printf '\n  ]\n'
    printf '}\n'
    exit 0
fi

# ==============================================================================
# OUTPUT GENERATION: HUMAN READABLE CLI REPORT
# ==============================================================================

echo ""
echo -e "${C_BOLD}═══════════════════════════════════════════════════════════════════════════════${C_RESET}"
echo -e " ${C_BOLD}LOGXAL AUDIT REPORT${C_RESET} · $(date -u '+%d %b %Y %H:%M UTC') · Server Score: ${C_BOLD}${SCORE} / 100${C_RESET}"
echo -e "${C_BOLD}═══════════════════════════════════════════════════════════════════════════════${C_RESET}"
echo ""

# Summary Pill
if [ "$SCORE" -ge 90 ]; then
    echo -e " Security Health Status: ${C_GREEN}● SECURE & OPTIMIZED (Score: ${SCORE}/100)${C_RESET}"
elif [ "$SCORE" -ge 60 ]; then
    echo -e " Security Health Status: ${C_YELLOW}● ACTION RECOMMENDED (Score: ${SCORE}/100)${C_RESET}"
else
    echo -e " Security Health Status: ${C_RED}● CRITICAL ATTENTION REQUIRED (Score: ${SCORE}/100)${C_RESET}"
fi
echo ""

# System Metrics Summary
echo -e " ${C_BOLD}System Baseline:${C_RESET}"
echo -e "   • OS: ${OS_NAME} ${OS_VERSION} (${OS_ARCH}) · Kernel: ${KERNEL_VERSION}"
echo -e "   • CPU: ${CPU_CORES} Core(s) · Load (1m): ${CPU_LOAD_1M}"
echo -e "   • Memory: ${USED_RAM_MB}MB / ${TOTAL_RAM_MB}MB used (${RAM_PERCENT}%)"
if [ "$TOTAL_SWAP_MB" -eq 0 ]; then
    echo -e "   • Swap: ${C_RED}0 MB (Missing)${C_RESET}"
else
    echo -e "   • Swap: ${USED_SWAP_MB}MB / ${TOTAL_SWAP_MB}MB (${SWAP_PERCENT}%)"
fi
echo -e "   • Storage: ${DISK_USED_GB}GB / ${DISK_TOTAL_GB}GB used (${DISK_PERCENT}%)"
echo -e "   • SSH Port: ${DETECTED_SSH_PORT} · Firewall: $([ "$FIREWALL_ACTIVE" = true ] && echo -e "${C_GREEN}Active ($FIREWALL_TYPE)${C_RESET}" || echo -e "${C_RED}Inactive${C_RESET}")"
echo ""

# Findings List
if [ ${#FINDING_IDS[@]} -eq 0 ]; then
    echo -e " ${C_GREEN}✅ No critical vulnerabilities or system risks detected!${C_RESET}"
else
    echo -e " ${C_BOLD}Detected Items (${#FINDING_IDS[@]}):${C_RESET}"
    for k in "${!FINDING_IDS[@]}"; do
        SEV_COLOR="$C_YELLOW"
        SEV_ICON="⚠️ "
        if [ "${FINDING_SEVERITIES[$k]}" = "critical" ]; then
            SEV_COLOR="$C_RED"
            SEV_ICON="🔴"
        elif [ "${FINDING_SEVERITIES[$k]}" = "info" ]; then
            SEV_COLOR="$C_CYAN"
            SEV_ICON="ℹ️ "
        fi
        echo -e "   ${SEV_ICON} ${SEV_COLOR}${C_BOLD}${FINDING_TITLES[$k]}${C_RESET}"
        echo -e "      ${C_DIM}${FINDING_DESCRIPTIONS[$k]}${C_RESET}"
    done
fi
echo ""

# Planned Hardening Actions
if [ ${#PLAN_TITLES[@]} -gt 0 ]; then
    echo -e " ${C_BOLD}Planned Automated Fixes:${C_RESET}"
    for p in "${!PLAN_TITLES[@]}"; do
        echo -e "   ${C_GREEN}✔${C_RESET} ${C_BOLD}${PLAN_TITLES[$p]}${C_RESET}"
        echo -e "      ${C_DIM}${PLAN_DETAILS[$p]}${C_RESET}"
    done
    echo ""
fi

# Conversion Banner
echo -e "┌─────────────────────────────────────────────────────────────────────────────┐"
echo -e "│  ${C_BOLD}${C_CYAN}🚀 AUTOMATE & SECURE YOUR VPS WITH LOGXAL (Autonomous SRE)${C_RESET}              │"
echo -e "├─────────────────────────────────────────────────────────────────────────────┤"
echo -e "│  Logxal turns unmanaged Linux VPS servers into self-healing infrastructure: │"
echo -e "│                                                                             │"
echo -e "│  ${C_GREEN}✔${C_RESET} ${C_BOLD}1-Click Auto-Hardening:${C_RESET} Fix firewall, ports & swap automatically      │"
echo -e "│  ${C_GREEN}✔${C_RESET} ${C_BOLD}AI Incident Diagnosis:${C_RESET} When an app crashes, Logxal explains WHY     │"
echo -e "│  ${C_GREEN}✔${C_RESET} ${C_BOLD}1-Click Deployments:${C_RESET} Git push to live VPS with auto SSL & reverse proxy │"
echo -e "│  ${C_GREEN}✔${C_RESET} ${C_BOLD}Automated Backups:${C_RESET} Daily encrypted database backups to S3/R2         │"
echo -e "│                                                                             │"
echo -e "│  ${C_BOLD}👉 Secure this server in 1 click (Free Trial):${C_RESET}                             │"
echo -e "│     ${C_CYAN}https://logxal.com/connect?ref=audit_cli${C_RESET}                                │"
echo -e "└─────────────────────────────────────────────────────────────────────────────┘"
echo ""

exit 0
