#!/bin/bash
# =============================================================================
# security-crypto.sh -- Encryption & Key Management
# =============================================================================
# Category: security | Bird: falcon | Tier: 1 | Node-aware: yes
# Absorbs: encrypt.sh, hsm.sh, parts of auth.sh (crypto)
# =============================================================================

TOOL_NAME="security-crypto"
TOOL_VERSION="3.0.0"
TOOL_TIER=1
TOOL_BIRD="falcon"
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}"

KEYS_DIR="/opt/binary/keys"
HMAC_KEY="/etc/binary/hmac.key"

_do_send_impl() {
    echo "=== Crypto Status: $(ts_local) ==="
    echo "  Node: ${NODE_ID}"
    local gpg_count=0
    command -v gpg &>/dev/null && gpg_count=$(gpg --list-keys 2>/dev/null | grep -c "^pub" || echo 0)
    echo "  GPG keys: ${gpg_count}"
    if [ -f "$HMAC_KEY" ]; then
        echo "  HMAC key: present (mode=$(stat -c '%a' "$HMAC_KEY" 2>/dev/null))"
    else echo "  HMAC key: MISSING"; fi
    [ -d "$KEYS_DIR" ] && echo "  Key files: $(find "$KEYS_DIR" -type f 2>/dev/null | wc -l)"
    tool_audit "send" "node=${NODE_ID}"
}

_do_status_impl() {
    local hmac="false" s="healthy"
    [ -f "$HMAC_KEY" ] && hmac="true"
    [ "$hmac" = "false" ] && s="degraded"
    echo "{\"tool\":\"${TOOL_NAME}\",\"node\":\"${NODE_ID}\",\"status\":\"${s}\",\"hmac_present\":${hmac},\"checked_at\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}"
}

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

do_encrypt() {
    local f="$1"; [ -f "$f" ] || { log_error "File not found: $f"; return 1; }
    gpg --symmetric --cipher-algo AES256 --batch --yes "$f" 2>/dev/null
    [ -f "${f}.gpg" ] && log_ok "Encrypted: ${f}.gpg" || { log_error "Failed"; return 1; }
    tool_audit "encrypt" "file=$f node=${NODE_ID}"
}

do_decrypt() {
    local f="$1"; [ -f "$f" ] || { log_error "File not found: $f"; return 1; }
    local out="${f%.gpg}"
    gpg --decrypt --batch --yes --output "$out" "$f" 2>/dev/null
    [ -f "$out" ] && log_ok "Decrypted: $out" || { log_error "Failed"; return 1; }
    tool_audit "decrypt" "file=$f node=${NODE_ID}"
}

do_rotate_key() {
    require_root || return 1
    [ -f "$HMAC_KEY" ] && cp "$HMAC_KEY" "${HMAC_KEY}.$(ts_file).bak"
    openssl rand -hex 32 > "$HMAC_KEY"; chmod 600 "$HMAC_KEY"; chown root:root "$HMAC_KEY"
    tool_audit "rotate_key" "hmac rotated node=${NODE_ID}"
    log_ok "HMAC key rotated"
}

tool_help() { echo "${TOOL_NAME} v${TOOL_VERSION} -- Encryption & Key Management"; echo "  --send|--status|--digest|--flush|--encrypt|--decrypt|--rotate-key"; }

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 "$@" ;;
    --encrypt) shift; do_encrypt "$@" ;; --decrypt) shift; do_decrypt "$@" ;;
    --rotate-key) do_rotate_key ;; --help) tool_help ;;
    *) handle_standard_command "$@" ;;
esac
