#!/usr/bin/env bash
set -euo pipefail
# gen_audit_keys.sh — Generate per-node AES-256 encryption keys for SCLS
#
# Creates one 256-bit (64-char hex) key per node:
#   - Engine-side (for decryption): /opt/sysc/engine/vault/node_keys/<NODE_ID>.key
#   - Node-side (for encryption):   /opt/binary/config/.k7x9m2/audit.key
#
# Usage: sudo bash gen_audit_keys.sh
# Must be run on Engine (669427).

# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------
readonly SCRIPT_NAME="gen_audit_keys"
readonly ENGINE_VAULT_DIR="/opt/sysc/engine/vault/node_keys"
readonly NODE_KEY_REMOTE_DIR="/opt/binary/config/.k7x9m2"
readonly NODE_KEY_REMOTE_FILE="audit.key"

# All fleet node IDs
readonly NODE_IDS=(199335 244939 333941 414342 558201 669427 714820 869377)

# Node ID to WG IP mapping
declare -A NODE_WG_IPS=(
    [199335]="10.69.69.5"   # DNS
    [244939]="10.69.69.3"   # Proxy
    [333941]="10.69.69.4"   # Filter
    [414342]="10.69.69.1"   # Shield
    [558201]="10.69.69.2"   # Origin
    [669427]="10.69.69.6"   # Engine
    [714820]="10.69.69.7"   # Payment
    [869377]="10.69.69.8"   # Vault
)

# Node ID to name mapping
declare -A NODE_NAMES=(
    [199335]="DNS"
    [244939]="Proxy"
    [333941]="Filter"
    [414342]="Shield"
    [558201]="Origin"
    [669427]="Engine"
    [714820]="Payment"
    [869377]="Vault"
)

# ---------------------------------------------------------------------------
# Logging
# ---------------------------------------------------------------------------
log() {
    local level="$1"; shift
    printf '[%s] [%s] [%s] %s\n' \
        "$(date -u '+%Y-%m-%dT%H:%M:%S.%NZ')" "$SCRIPT_NAME" "$level" "$*"
}

# ---------------------------------------------------------------------------
# Preflight checks
# ---------------------------------------------------------------------------
if [[ "$(id -u)" -ne 0 ]]; then
    log "FATAL" "Must run as root (sudo)"
    exit 1
fi

if ! command -v openssl &>/dev/null; then
    log "FATAL" "openssl not found in PATH"
    exit 1
fi

# Verify we are on Engine
local_node_id=""
if [[ -f /etc/binary/node_id ]]; then
    local_node_id="$(< /etc/binary/node_id)"
fi
if [[ "$local_node_id" != "669427" ]]; then
    log "WARN" "This script is designed to run on Engine (669427), local node_id='${local_node_id}'"
    log "WARN" "Proceeding anyway — Engine vault directory will be created locally"
fi

# ---------------------------------------------------------------------------
# Create Engine vault directory
# ---------------------------------------------------------------------------
if [[ ! -d "$ENGINE_VAULT_DIR" ]]; then
    log "INFO" "Creating vault directory: ${ENGINE_VAULT_DIR}"
    mkdir -p "$ENGINE_VAULT_DIR"
    chmod 700 "$ENGINE_VAULT_DIR"
    chown root:root "$ENGINE_VAULT_DIR"
else
    log "INFO" "Vault directory already exists: ${ENGINE_VAULT_DIR}"
fi

# ---------------------------------------------------------------------------
# Generate keys
# ---------------------------------------------------------------------------
log "INFO" "Generating AES-256 keys for ${#NODE_IDS[@]} nodes..."

declare -A GENERATED_KEYS

for node_id in "${NODE_IDS[@]}"; do
    local_key_file="${ENGINE_VAULT_DIR}/${node_id}.key"

    if [[ -f "$local_key_file" ]]; then
        log "WARN" "Key already exists for node ${node_id} (${NODE_NAMES[$node_id]}), skipping"
        log "WARN" "  To regenerate, remove: ${local_key_file}"
        GENERATED_KEYS[$node_id]="$(< "$local_key_file")"
        continue
    fi

    # Generate 256-bit key (64 hex characters)
    key_hex="$(openssl rand -hex 32)"

    if [[ ${#key_hex} -ne 64 ]]; then
        log "FATAL" "Key generation produced unexpected length: ${#key_hex} (expected 64)"
        exit 1
    fi

    # Write Engine-side key file
    printf '%s' "$key_hex" > "$local_key_file"
    chmod 600 "$local_key_file"
    chown root:root "$local_key_file"

    GENERATED_KEYS[$node_id]="$key_hex"
    log "INFO" "Generated key for node ${node_id} (${NODE_NAMES[$node_id]}): ${key_hex:0:8}..."
done

# ---------------------------------------------------------------------------
# Summary + deployment commands
# ---------------------------------------------------------------------------
echo ""
echo "========================================================================"
echo "  SCLS Audit Key Generation Complete"
echo "========================================================================"
echo ""
printf '  %-8s  %-10s  %-14s  %s\n' "NODE_ID" "NAME" "WG_IP" "KEY_PREFIX"
printf '  %-8s  %-10s  %-14s  %s\n' "--------" "----------" "--------------" "----------"

for node_id in "${NODE_IDS[@]}"; do
    key="${GENERATED_KEYS[$node_id]:-unknown}"
    printf '  %-8s  %-10s  %-14s  %s...\n' \
        "$node_id" "${NODE_NAMES[$node_id]}" "${NODE_WG_IPS[$node_id]}" "${key:0:8}"
done

echo ""
echo "========================================================================"
echo "  Engine-side keys stored in: ${ENGINE_VAULT_DIR}/"
echo "========================================================================"
echo ""
echo "--- Deployment Commands (run from Engine via SSH) ---"
echo ""

for node_id in "${NODE_IDS[@]}"; do
    wg_ip="${NODE_WG_IPS[$node_id]}"
    key="${GENERATED_KEYS[$node_id]:-}"

    if [[ -z "$key" ]]; then
        log "WARN" "No key for node ${node_id}, skipping deployment command"
        continue
    fi

    if [[ "$node_id" == "669427" ]]; then
        # Engine itself — deploy locally
        cat <<EOCMD
# --- Engine (${node_id}) — local deployment ---
mkdir -p ${NODE_KEY_REMOTE_DIR}
printf '%s' '${key}' > ${NODE_KEY_REMOTE_DIR}/${NODE_KEY_REMOTE_FILE}
chmod 600 ${NODE_KEY_REMOTE_DIR}/${NODE_KEY_REMOTE_FILE}
chown root:root ${NODE_KEY_REMOTE_DIR}/${NODE_KEY_REMOTE_FILE}

EOCMD
    else
        # Remote nodes — SSH via WG mesh
        cat <<EOCMD
# --- ${NODE_NAMES[$node_id]} (${node_id}) @ ${wg_ip} ---
ssh -i /opt/binary/config/keys/gabriella -p 9922 -o StrictHostKeyChecking=no admin@${wg_ip} \\
  "sudo mkdir -p ${NODE_KEY_REMOTE_DIR} && \\
   printf '%s' '${key}' | sudo tee ${NODE_KEY_REMOTE_DIR}/${NODE_KEY_REMOTE_FILE} >/dev/null && \\
   sudo chmod 600 ${NODE_KEY_REMOTE_DIR}/${NODE_KEY_REMOTE_FILE} && \\
   sudo chown root:root ${NODE_KEY_REMOTE_DIR}/${NODE_KEY_REMOTE_FILE}"

EOCMD
    fi
done

echo "========================================================================"
echo "  Verify deployment with:"
echo "    ssh admin@<WG_IP> 'sudo cat ${NODE_KEY_REMOTE_DIR}/${NODE_KEY_REMOTE_FILE} | head -c 8'"
echo "========================================================================"

log "INFO" "Key generation complete. ${#GENERATED_KEYS[@]} keys ready."
