#!/usr/bin/env bash
#
# onx-exim-conf-write — /etc/exim/exim.conf icerigini atomic yaz + syntax test
#
# Akis:
#   1. Yedek al: /etc/exim/exim.conf → /etc/exim/exim.conf.bak-YYYYMMDD-HHMMSS
#   2. Yeni icerigi temp dosyaya yaz
#   3. exim -bV -C <temp> → syntax check
#   4. Pass: atomic mv temp → real path
#   5. Fail: temp sil, hata don, real dosya degismez
#
# stdin: {"content":"... full file ..."}
# stdout: {"ok":true,"path":"...","backup":"...","bytes_written":N,"checked":true}

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

require_root
require_cmd jq

INPUT=$(cat)

# Validate JSON
echo "$INPUT" | jq -e 'type == "object" and has("content")' >/dev/null 2>&1 \
    || json_fail 1 "Eksik alan: content"

CONTENT=$(echo "$INPUT" | jq -r '.content')

# Bos icerige izin verme (yanlislikla bos yazim engelle)
if [[ -z "$CONTENT" || ${#CONTENT} -lt 50 ]]; then
    json_fail 1 "Icerik bos veya cok kisa (en az 50 byte)"
fi

# Max size (1MB) — exim.conf normalde 50-200KB
MAX_BYTES=1048576
if [[ ${#CONTENT} -gt $MAX_BYTES ]]; then
    json_fail 1 "Icerik cok buyuk (max 1MB)"
fi

# Conf path auto-detect
CONF_PATH=""
for p in /etc/exim/exim.conf /etc/exim4/exim4.conf; do
    if [[ -f "$p" ]]; then
        CONF_PATH="$p"
        break
    fi
done

if [[ -z "$CONF_PATH" ]]; then
    json_fail 2 "exim config dosyasi bulunamadi (/etc/exim/exim.conf yok — Exim kurulu mu?)"
fi

# Exim binary
EXIM_BIN=""
for bin in /usr/sbin/exim /usr/sbin/exim4; do
    [[ -x "$bin" ]] && { EXIM_BIN="$bin"; break; }
done
[[ -z "$EXIM_BIN" ]] && json_fail 2 "exim binary bulunamadi"

# 1) Backup (tarihli)
TS=$(date +%Y%m%d-%H%M%S)
BACKUP_PATH="${CONF_PATH}.bak-${TS}"
cp -p "$CONF_PATH" "$BACKUP_PATH" || json_fail 3 "backup olusturulamadi: $BACKUP_PATH"

# 2) Yeni icerigi temp dosyaya yaz (same dir, atomic mv icin)
CONF_DIR=$(dirname "$CONF_PATH")
TMP_FILE=$(mktemp -p "$CONF_DIR" ".exim.conf-XXXXXX") || json_fail 3 "mktemp basarisiz"

# Cleanup trap: hata olursa temp sil
trap 'rm -f "$TMP_FILE" 2>/dev/null || true' EXIT

# Mode + ownership: exim.conf normalde root:exim 0640 veya root:root 0644
# Mevcut dosyanin mode'unu koru
ORIG_MODE=$(stat -c%a "$CONF_PATH" 2>/dev/null || echo "0644")
ORIG_OWNER=$(stat -c%U:%G "$CONF_PATH" 2>/dev/null || echo "root:root")

printf '%s' "$CONTENT" > "$TMP_FILE"
chmod "$ORIG_MODE" "$TMP_FILE" 2>/dev/null || true
chown "$ORIG_OWNER" "$TMP_FILE" 2>/dev/null || true

# 3) Syntax check — exim -bV -C <temp>
if ! BV_OUT=$("$EXIM_BIN" -bV -C "$TMP_FILE" 2>&1); then
    # Hatayi don — temp otomatik silinecek (trap)
    ESCAPED=$(printf '%s' "$BV_OUT" | jq -Rs '.')
    echo "{\"ok\":false,\"error\":\"exim -bV syntax check basarisiz\",\"detail\":${ESCAPED},\"backup\":\"${BACKUP_PATH}\"}" >&2
    exit 3
fi

# 4) Atomic mv — temp → real (rename syscall atomic)
BYTES=${#CONTENT}
if ! mv -f "$TMP_FILE" "$CONF_PATH"; then
    json_fail 3 "atomic mv basarisiz"
fi

# Trap'i temizle (basari)
trap - EXIT

# JSON cikti
echo "{\"ok\":true,\"path\":\"${CONF_PATH}\",\"backup\":\"${BACKUP_PATH}\",\"bytes_written\":${BYTES},\"checked\":true,\"message\":\"exim.conf yazildi + syntax OK\"}"
exit 0
