#!/usr/bin/env bash
# =============================================================================
# onx-fail2ban-ban — Manually ban an IP within a fail2ban jail
#
# Input (stdin JSON):
#   { "jail": "sshd", "ip": "1.2.3.4" }
#
# Output (stdout JSON):
#   { "jail":"sshd", "ip":"1.2.3.4", "banned": true }
#
# Deployed to: /usr/local/onoxsoft/bin/onx-fail2ban-ban
# =============================================================================

set -euo pipefail

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
# shellcheck source=_lib/common.sh
source "${SCRIPT_DIR}/_lib/common.sh"

require_root
onx_json_input

JAIL=$(onx_json_field "jail" "")
IP=$(onx_json_field   "ip"   "")

[[ -n "${JAIL}" ]] || onx_die 1 "jail required"
[[ -n "${IP}"   ]] || onx_die 1 "ip required"
[[ "${JAIL}" =~ ^[a-zA-Z0-9_-]{1,40}$ ]] || onx_die 1 "invalid jail '${JAIL}'"

# IPv4 (CIDR opsiyonel) veya IPv6 kabul et
if [[ "${IP}" == *:* ]]; then
    [[ "${IP}" =~ ^[0-9a-fA-F:]+(/[0-9]{1,3})?$ ]] || onx_die 1 "invalid ipv6 '${IP}'"
else
    [[ "${IP}" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}(/[0-9]{1,2})?$ ]] || onx_die 1 "invalid ip/cidr '${IP}'"
fi

if [[ "${MOCK_MODE}" == "1" ]] || ! command -v fail2ban-client >/dev/null 2>&1; then
    onx_audit "onx-fail2ban" "MOCK ban jail=${JAIL} ip=${IP}"
    jq -nc --arg j "${JAIL}" --arg i "${IP}" '{jail:$j, ip:$i, banned:true, mock:true}'
    exit 0
fi

# Idempotency: skip if already banned in this jail
if fail2ban-client status "${JAIL}" 2>/dev/null | grep -q "${IP}"; then
    onx_log "fail2ban: ${IP} already banned in ${JAIL}"
else
    fail2ban-client set "${JAIL}" banip "${IP}" >/dev/null \
        || onx_die 3 "fail2ban-client set ${JAIL} banip ${IP} failed"
fi

onx_audit "onx-fail2ban" "ban jail=${JAIL} ip=${IP}"
jq -nc --arg j "${JAIL}" --arg i "${IP}" '{jail:$j, ip:$i, banned:true}'
