#!/usr/bin/env bash
#
# onx-fail2ban-settings-write — Global fail2ban ayarlarını /etc/fail2ban/jail.local'a yaz.
#
# Input (stdin JSON):
#   {
#     "default_bantime": 3600,
#     "default_findtime": 600,
#     "default_maxretry": 5,
#     "default_action": "%(action_mwl)s",
#     "destemail": "admin@example.com",
#     "sender": "fail2ban@example.com",
#     "dbpurgeage": 86400,
#     "dbmaxmatches": 10,
#     "logtarget": "/var/log/fail2ban.log",
#     "loglevel": "INFO",
#     "notify_on_ban": "1"|"0",
#     "recidive_enabled": "1"|"0"
#   }
#
# Output: {"ok":true,"updated_keys":[...],"reloaded":true,"recidive_enabled":bool}

set -euo pipefail

input="$(cat)"
readonly JAIL_LOCAL="/etc/fail2ban/jail.local"
readonly RECIDIVE_FILE="/etc/fail2ban/jail.d/recidive.local"
readonly LOG_TAG="onox-fail2ban-cfg"

get() { echo "$input" | jq -r ".$1 // empty"; }

# Mevcut ignoreip'i koru
existing_ignoreip=""
if [[ -f "$JAIL_LOCAL" ]] && grep -qE '^[[:space:]]*ignoreip[[:space:]]*=' "$JAIL_LOCAL"; then
    existing_ignoreip="$(grep -E '^[[:space:]]*ignoreip[[:space:]]*=' "$JAIL_LOCAL" | head -1 | sed -E 's/^[^=]+=[[:space:]]*//')"
fi
[[ -z "$existing_ignoreip" ]] && existing_ignoreip="127.0.0.1/8 ::1"

# ── Build new jail.local [DEFAULT] section ────────────────────────────────
default_bantime="$(get default_bantime)"
default_findtime="$(get default_findtime)"
default_maxretry="$(get default_maxretry)"
default_action="$(get default_action)"
destemail="$(get destemail)"
sender="$(get sender)"
dbpurgeage="$(get dbpurgeage)"
dbmaxmatches="$(get dbmaxmatches)"
logtarget="$(get logtarget)"
loglevel="$(get loglevel)"
notify_on_ban="$(get notify_on_ban)"

# Default action — notify aktifse mwl, değilse plain
if [[ "$notify_on_ban" == "1" ]]; then
    [[ -z "$default_action" ]] && default_action="%(action_mwl)s"
else
    [[ -z "$default_action" ]] && default_action="%(action_)s"
fi

# Validate numerics
for v in default_bantime default_findtime default_maxretry dbpurgeage dbmaxmatches; do
    val="${!v}"
    if [[ -n "$val" ]] && ! [[ "$val" =~ ^[0-9]+$ ]]; then
        jq -nc --arg k "$v" --arg val "$val" '{ok:false,error:"not a number",key:$k,value:$val}' >&2
        exit 1
    fi
done

# Backup current
[[ -f "$JAIL_LOCAL" ]] && cp -a "$JAIL_LOCAL" "${JAIL_LOCAL}.bak.$(date +%s)"

# Write new file
{
    echo "# /etc/fail2ban/jail.local — Managed by ONOX panel"
    echo "# Use the panel UI under Security → fail2ban to edit these values."
    echo ""
    echo "[DEFAULT]"
    echo "ignoreip = ${existing_ignoreip}"
    [[ -n "$default_bantime"  ]] && echo "bantime  = ${default_bantime}"
    [[ -n "$default_findtime" ]] && echo "findtime = ${default_findtime}"
    [[ -n "$default_maxretry" ]] && echo "maxretry = ${default_maxretry}"
    [[ -n "$destemail"        ]] && echo "destemail = ${destemail}"
    [[ -n "$sender"           ]] && echo "sender   = ${sender}"
    [[ -n "$default_action"   ]] && echo "action   = ${default_action}"
} > "$JAIL_LOCAL"

# ── fail2ban.local (logtarget, loglevel, dbpurgeage) ──────────────────────
if [[ -n "$logtarget" || -n "$loglevel" || -n "$dbpurgeage" || -n "$dbmaxmatches" ]]; then
    cat > /etc/fail2ban/fail2ban.local <<EOF
# /etc/fail2ban/fail2ban.local — Managed by ONOX panel
[Definition]
$([[ -n "$loglevel"     ]] && echo "loglevel  = $loglevel")
$([[ -n "$logtarget"    ]] && echo "logtarget = $logtarget")
$([[ -n "$dbpurgeage"   ]] && echo "dbpurgeage = $dbpurgeage")
$([[ -n "$dbmaxmatches" ]] && echo "dbmaxmatches = $dbmaxmatches")
EOF
fi

# ── Recidive jail toggle ──────────────────────────────────────────────────
recidive_enabled="$(get recidive_enabled)"
if [[ "$recidive_enabled" == "1" ]]; then
    cat > "$RECIDIVE_FILE" <<EOF
[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
banaction = %(banaction_allports)s
bantime  = 604800
findtime = 86400
maxretry = 3
EOF
else
    [[ -f "$RECIDIVE_FILE" ]] && rm -f "$RECIDIVE_FILE"
fi

# ── Reload / restart ──────────────────────────────────────────────────────
reloaded=true
if command -v fail2ban-client &>/dev/null; then
    # Some changes (logtarget) require restart, not reload
    if [[ -n "$logtarget" ]] && command -v systemctl &>/dev/null; then
        systemctl restart fail2ban 2>/dev/null || reloaded=false
    else
        fail2ban-client reload 2>/dev/null || reloaded=false
    fi
fi

updated_keys="$(echo "$input" | jq -c 'keys')"

logger -t "$LOG_TAG" "Settings updated (keys=$updated_keys)"

jq -nc \
    --argjson updated_keys "$updated_keys" \
    --argjson reloaded "$reloaded" \
    --argjson recidive "$([[ "$recidive_enabled" == "1" ]] && echo true || echo false)" \
    '{ok:true,updated_keys:$updated_keys,reloaded:$reloaded,recidive_enabled:$recidive}'
