#!/usr/bin/env bash
#
# onx-dovecot-config-set — Generic Dovecot key/value setter (v83)
#
# /etc/dovecot/conf.d/onox-overrides.conf dosyasına idempotent yazar.
# Aynı key tekrar gelirse override edilir. doveconf -n syntax check + reload.
#
# stdin:  {"settings":[{"key":"mail_location","value":"maildir:/var/vmail/%d/%n/Maildir"},…]}
# stdout: {"ok":true,"applied":N,"keys":["mail_location",…],"syntax_ok":true,"reloaded":true}
#
# WHITELIST (güvenlik) — sadece bu key'ler kabul edilir:
#   protocols, mail_location, mail_uid, mail_gid, first_valid_uid, mailbox_format,
#   auth_mechanisms, disable_plaintext_auth, passdb_driver, userdb_driver,
#   auth_username_format, auth_verbose, auth_debug,
#   ssl, ssl_cert, ssl_key, ssl_min_protocol, ssl_cipher_list,
#   imap_idle_notify_interval, imap_max_line_length, imap_logout_format,
#   pop3_uidl_format, pop3_lock_session, pop3_no_flag_updates, pop3_client_workarounds,
#   quota_plugin, quota_rule, quota_rule_default, quota_warning,
#   sieve, sieve_dir, sieve_default, sieve_max_script_size, sieve_max_actions,
#   lmtp_save_to_detail_mailbox, lmtp_user_concurrency_limit,
#   log_path, mail_debug, master_users
#
# Exit codes: 0 ok, 1 invalid input, 2 preflight, 3 execution

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

require_root
require_cmd doveconf
require_cmd systemctl

onx_json_input

CONF_DIR="/etc/dovecot/conf.d"
OVERRIDE_FILE="${CONF_DIR}/onox-overrides.conf"
TS=$(date -Iseconds)

[[ -d "$CONF_DIR" ]] || onx_die 2 "/etc/dovecot/conf.d/ dizini yok"

# Whitelist
WHITELIST=(
    protocols mail_location mail_uid mail_gid first_valid_uid mailbox_format
    auth_mechanisms disable_plaintext_auth passdb_driver userdb_driver
    auth_username_format auth_verbose auth_debug
    ssl ssl_cert ssl_key ssl_min_protocol ssl_cipher_list
    imap_idle_notify_interval imap_max_line_length imap_logout_format
    pop3_uidl_format pop3_lock_session pop3_no_flag_updates pop3_client_workarounds
    quota_plugin quota_rule quota_rule_default quota_warning
    sieve sieve_dir sieve_default sieve_max_script_size sieve_max_actions
    lmtp_save_to_detail_mailbox lmtp_user_concurrency_limit
    log_path mail_debug master_users
)
is_whitelisted() {
    local k="$1"
    for w in "${WHITELIST[@]}"; do [[ "$w" == "$k" ]] && return 0; done
    return 1
}

SETTINGS_LEN=$(echo "$INPUT" | jq '.settings | length' 2>/dev/null || echo 0)
[[ "$SETTINGS_LEN" -lt 1 ]] && onx_die 1 "'settings' dizisi boş"

# Validate
while IFS= read -r setting; do
    KEY=$(echo "$setting" | jq -r '.key // empty')
    [[ -z "$KEY" ]] && onx_die 1 "Eksik 'key' alanı"
    is_whitelisted "$KEY" || onx_die 1 "Whitelist dışı key: '$KEY'"
done < <(echo "$INPUT" | jq -c '.settings[]')

# Mevcut override dosyasından ilgili key'leri sil (idempotent)
if [[ -f "$OVERRIDE_FILE" ]]; then
    BACKUP="${OVERRIDE_FILE}.onx-bak.$(date +%s)"
    cp "$OVERRIDE_FILE" "$BACKUP"
    while IFS= read -r setting; do
        KEY=$(echo "$setting" | jq -r '.key')
        sed -i -E "/^[[:space:]]*${KEY}[[:space:]]*=/d" "$OVERRIDE_FILE"
    done < <(echo "$INPUT" | jq -c '.settings[]')
fi

# Yeni satırları ekle
{
    if [[ ! -f "$OVERRIDE_FILE" ]] || [[ ! -s "$OVERRIDE_FILE" ]]; then
        echo "# ONOX-managed Dovecot overrides"
        echo "# Edited via Onoxsoft Admin Panel — onx-dovecot-config-set"
        echo "# Generated: ${TS}"
        echo ""
    fi
    echo "# Updated: ${TS}"
    while IFS= read -r setting; do
        KEY=$(echo "$setting" | jq -r '.key')
        VALUE=$(echo "$setting" | jq -r '.value // ""')
        echo "${KEY} = ${VALUE}"
    done < <(echo "$INPUT" | jq -c '.settings[]')
    echo ""
} >> "$OVERRIDE_FILE"

# Syntax check
if ! doveconf -n >/dev/null 2>&1; then
    [[ -f "${OVERRIDE_FILE}.onx-bak."* ]] 2>/dev/null && {
        latest_bak=$(ls -t "${OVERRIDE_FILE}".onx-bak.* 2>/dev/null | head -1)
        [[ -n "$latest_bak" ]] && mv "$latest_bak" "$OVERRIDE_FILE"
    }
    onx_die 3 "doveconf -n başarısız — değişiklik geri alındı"
fi

# Cleanup eski backup'lar
rm -f "${OVERRIDE_FILE}".onx-bak.* 2>/dev/null || true

# Reload
RELOADED=false
if systemctl reload dovecot 2>/dev/null; then
    RELOADED=true
fi

KEYS_JSON=$(echo "$INPUT" | jq -c '[.settings[].key]')
json_ok "$(jq -nc \
    --argjson n "$SETTINGS_LEN" \
    --argjson keys "$KEYS_JSON" \
    --argjson r "$RELOADED" \
    '{ok:true, applied:$n, keys:$keys, syntax_ok:true, reloaded:$r}')"
