#!/usr/bin/env bash
#
# onx-dovecot-config-pop3-enable — POP3 + POP3S aktif et (v83)
#
# Dovecot kurulumlarının çoğunda /etc/dovecot/dovecot.conf'taki `protocols`
# satırı SADECE `imap` içerir. Bu script:
#   1. /etc/dovecot/dovecot.conf -> protocols satırına "pop3" ekler
#      (zaten varsa idempotent — atlar).
#   2. /etc/dovecot/conf.d/10-master.conf -> service pop3-login bloğunda
#      inet_listener pop3 (port 110) + pop3s (port 995) port=0 OLMAMALI.
#   3. /etc/dovecot/conf.d/20-pop3.conf varsa kalır (yoksa minimal yazılır).
#   4. doveconf -n syntax check.
#   5. systemctl restart dovecot.
#   6. nc -zv localhost 110 + 995 — port binding doğrula.
#
# stdin:  {} (no args)
# stdout: {"ok":true,"pop3_added":true,"protocols":"imap pop3 lmtp sieve",
#          "ports_open":{"110":true,"995":true},"message":"..."}
#
# Exit codes:
#   0 — success
#   1 — invalid input
#   2 — preflight (dovecot/doveconf yok)
#   3 — execution fail (syntax/restart/port bind)

set -euo pipefail
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
source "${SCRIPT_DIR}/_lib/common.sh"

require_root
require_cmd doveconf
require_cmd systemctl

# v83.1: nc bağımlılığı kaldırıldı — bash builtin /dev/tcp + ss fallback
# (RHEL/AlmaLinux 9 minimal install'da ncat/nc yok, fakat ss her zaman var)
check_port() {
    local port="$1"
    if ( exec 3<>/dev/tcp/127.0.0.1/${port} ) 2>/dev/null; then
        exec 3<&-; exec 3>&-
        echo "true"
    elif command -v ss >/dev/null 2>&1 && ss -tlnH "( sport = :${port} )" 2>/dev/null | grep -q .; then
        echo "true"
    else
        echo "false"
    fi
}

onx_json_input

DOVECOT_CONF="/etc/dovecot/dovecot.conf"
MASTER_CONF="/etc/dovecot/conf.d/10-master.conf"
POP3_CONF="/etc/dovecot/conf.d/20-pop3.conf"
TS=$(date -Iseconds)
BACKUP_SUFFIX=".onx-bak.$(date +%s)"

[[ -f "$DOVECOT_CONF" ]] || onx_die 2 "/etc/dovecot/dovecot.conf bulunamadı"
[[ -f "$MASTER_CONF" ]]  || onx_die 2 "/etc/dovecot/conf.d/10-master.conf bulunamadı"

# ── 1. protocols satırını oku ─────────────────────────────────────────────────
CURRENT_PROTOCOLS=$(grep -E '^[[:space:]]*protocols[[:space:]]*=' "$DOVECOT_CONF" 2>/dev/null | tail -1 | sed -E 's/^[[:space:]]*protocols[[:space:]]*=[[:space:]]*//' || echo "")
POP3_ADDED=false

if [[ -z "$CURRENT_PROTOCOLS" ]]; then
    # protocols satırı hiç yok — ekle
    cp "$DOVECOT_CONF" "${DOVECOT_CONF}${BACKUP_SUFFIX}"
    {
        echo ""
        echo "# Added by onx-dovecot-config-pop3-enable @ ${TS}"
        echo "protocols = imap pop3 lmtp sieve"
    } >> "$DOVECOT_CONF"
    NEW_PROTOCOLS="imap pop3 lmtp sieve"
    POP3_ADDED=true
elif ! echo "$CURRENT_PROTOCOLS" | grep -qw "pop3"; then
    # pop3 yok → ekle
    cp "$DOVECOT_CONF" "${DOVECOT_CONF}${BACKUP_SUFFIX}"
    NEW_PROTOCOLS="${CURRENT_PROTOCOLS} pop3"
    # Tüm protocols satırlarını sil + tek satır yaz
    sed -i -E "/^[[:space:]]*protocols[[:space:]]*=/d" "$DOVECOT_CONF"
    {
        echo ""
        echo "# Added by onx-dovecot-config-pop3-enable @ ${TS}"
        echo "protocols = ${NEW_PROTOCOLS}"
    } >> "$DOVECOT_CONF"
    POP3_ADDED=true
else
    NEW_PROTOCOLS="$CURRENT_PROTOCOLS"
fi

# ── 2. 10-master.conf — service pop3-login bloğu inet_listener kontrol ───────
# Dovecot pop3-login default bloğu zaten 110/995 inet_listener içerir, ancak
# port=0 ile disable edilmiş olabilir. Tüm "service pop3-login" altındaki
# inet_listener pop3/pop3s bloklarındaki "port = 0" satırını kaldırırız.
if grep -qE "service[[:space:]]+pop3-login" "$MASTER_CONF"; then
    cp "$MASTER_CONF" "${MASTER_CONF}${BACKUP_SUFFIX}"

    # awk: pop3-login service bloğunda inet_listener pop3/pop3s bloklarındaki port=0'ı sil
    awk '
        BEGIN { in_svc=0; in_lst=0 }
        /^[[:space:]]*service[[:space:]]+pop3-login[[:space:]]*\{/ { in_svc=1 }
        in_svc && /^[[:space:]]*inet_listener[[:space:]]+pop3s?[[:space:]]*\{/ { in_lst=1 }
        {
            if (in_lst && $0 ~ /^[[:space:]]*port[[:space:]]*=[[:space:]]*0[[:space:]]*$/) next
            print
        }
        in_lst && /^[[:space:]]*\}[[:space:]]*$/ { in_lst=0 }
        in_svc && /^[[:space:]]*\}[[:space:]]*$/ && !in_lst { in_svc=0 }
    ' "${MASTER_CONF}${BACKUP_SUFFIX}" > "$MASTER_CONF"
fi

# ── 3. 20-pop3.conf eksikse minimal yaz ──────────────────────────────────────
if [[ ! -f "$POP3_CONF" ]]; then
    cat > "$POP3_CONF" <<'POP3CONF'
##
## POP3 specific settings - onx auto-generated
##
protocol pop3 {
    pop3_uidl_format = %08Xu%08Xv
    pop3_no_flag_updates = no
    pop3_save_uidl = yes
    pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
POP3CONF
fi

# ── 4. doveconf -n syntax check ──────────────────────────────────────────────
if ! doveconf -n >/dev/null 2>&1; then
    # Rollback
    [[ -f "${DOVECOT_CONF}${BACKUP_SUFFIX}" ]] && mv "${DOVECOT_CONF}${BACKUP_SUFFIX}" "$DOVECOT_CONF"
    [[ -f "${MASTER_CONF}${BACKUP_SUFFIX}" ]]  && mv "${MASTER_CONF}${BACKUP_SUFFIX}" "$MASTER_CONF"
    onx_die 3 "doveconf -n başarısız — değişiklik geri alındı"
fi

# ── 5. systemctl restart dovecot ─────────────────────────────────────────────
if ! systemctl restart dovecot 2>/dev/null; then
    onx_die 3 "systemctl restart dovecot başarısız"
fi

# 1-2sn bekle (port bind)
sleep 2

# ── 6. Port verify (bash builtin /dev/tcp + ss fallback) ─────────────────────
PORT_110=$(check_port 110)
PORT_995=$(check_port 995)

# Backup'ları temizle (başarılıysa)
rm -f "${DOVECOT_CONF}${BACKUP_SUFFIX}" "${MASTER_CONF}${BACKUP_SUFFIX}" 2>/dev/null || true

# JSON çıktı
PROTOCOLS_JSON=$(printf '%s' "$NEW_PROTOCOLS" | jq -Rs '.')
json_ok "$(jq -nc \
    --argjson added "$POP3_ADDED" \
    --argjson protocols "$PROTOCOLS_JSON" \
    --argjson p110 "$PORT_110" \
    --argjson p995 "$PORT_995" \
    '{
        ok: true,
        pop3_added: $added,
        protocols: $protocols,
        ports_open: {"110": $p110, "995": $p995},
        message: ($added | if . then "POP3 etkinleştirildi (Dovecot yeniden başlatıldı)" else "POP3 zaten etkin" end)
    }')"
