#!/usr/bin/env bash
# onx-sieve-write — Per-mailbox Sieve script üretir + doveadm ile aktif eder.
#
# stdin:
#   {
#     "email":"alice@example.com",
#     "vmail_uid":"vmail",
#     "rules": [
#         {"type":"whitelist","sender":"foo@x.tr"},
#         {"type":"blacklist","sender":"spam@y.tr"},
#         {"type":"filter","header":"Subject","contains":"newsletter","action":"fileinto","mailbox":"Bulletin"},
#         {"type":"vacation","subject":"Tatildeyim","days":7,"message":"15 Mayıs'ta dönüyorum."}
#     ],
#     "boxtrapper":true,
#     "raw_script": "require [\"fileinto\"]; …"   (opsiyonel: raw mode advanced kullanıcı)
#   }
#
# stdout: {"ok":true,"script_path":"…","bytes":NNN,"message":"…"}
#
# Notlar:
# - Sieve script /var/vmail/<domain>/<local>/sieve/managesieve.sieve altına yazılır
#   (Dovecot Pigeonhole sieve_dir = ~/sieve).
# - rules dizisinden Sieve syntax üretir; advanced mode "raw_script" verilirse o kullanılır.
# - boxtrapper=true ise whitelist dışı tüm gelen postalar "Quarantine" klasörüne taşınır.

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

require_root
require_cmd jq

INPUT="$(cat)"
[[ -n "$INPUT" ]] || json_fail 1 "Eksik stdin"

EMAIL="$(echo "$INPUT" | jq -r '.email // ""')"
RAW="$(echo "$INPUT" | jq -r '.raw_script // ""')"
BOXTRAPPER="$(echo "$INPUT" | jq -r '.boxtrapper // false')"

[[ -n "$EMAIL" ]] || json_fail 1 "Eksik alan: email"
onx_validate_email "$EMAIL"

DOMAIN="$ONX_EMAIL_DOMAIN"
LOCAL="$ONX_EMAIL_LOCAL"
VMAIL_BASE="/var/vmail/${DOMAIN}/${LOCAL}"

# Maildir / sieve klasörü oluştur (Dovecot ilk login'de açar ama biz garanti edelim)
SIEVE_DIR="${VMAIL_BASE}/sieve"
mkdir -p "$SIEVE_DIR"
chown -R vmail:vmail "$VMAIL_BASE" 2>/dev/null || true
chmod 700 "$SIEVE_DIR" 2>/dev/null || true

SIEVE_FILE="${SIEVE_DIR}/managesieve.sieve"
SIEVE_TMP="$(mktemp -t onx-sieve.XXXXXX)"
trap 'rm -f "$SIEVE_TMP"' EXIT

# --- Raw mode (advanced) ---
if [[ -n "$RAW" && "$RAW" != "null" ]]; then
    printf '%s\n' "$RAW" > "$SIEVE_TMP"
else
    # --- Generate from rules ---
    {
        printf '# Auto-generated by Onoxsoft on %s\n' "$(date -u +%FT%TZ)"
        printf 'require ["fileinto","envelope","vacation","imap4flags","copy","reject"];\n\n'

        # Whitelist/blacklist rules
        WL="$(echo "$INPUT" | jq -r '[.rules[]? | select(.type=="whitelist") | .sender] | @json')"
        BL="$(echo "$INPUT" | jq -r '[.rules[]? | select(.type=="blacklist") | .sender] | @json')"

        # Blacklist: discard
        if [[ "$BL" != "[]" && "$BL" != "null" ]]; then
            printf '# --- Blacklist (reject) ---\n'
            echo "$INPUT" | jq -r '.rules[]? | select(.type=="blacklist") | .sender' | while read -r s; do
                [[ -n "$s" ]] || continue
                printf 'if envelope :is "from" "%s" { reject "Mail not accepted."; stop; }\n' "$s"
            done
            printf '\n'
        fi

        # Filter rules
        printf '# --- Filter rules ---\n'
        echo "$INPUT" | jq -c '.rules[]? | select(.type=="filter")' | while read -r row; do
            [[ -n "$row" ]] || continue
            HDR="$(echo "$row" | jq -r '.header // "Subject"')"
            CONT="$(echo "$row" | jq -r '.contains // ""')"
            ACT="$(echo "$row" | jq -r '.action // "fileinto"')"
            MBX="$(echo "$row" | jq -r '.mailbox // "INBOX"')"
            [[ -n "$CONT" ]] || continue
            if [[ "$ACT" == "fileinto" ]]; then
                printf 'if header :contains "%s" "%s" { fileinto "%s"; stop; }\n' "$HDR" "$CONT" "$MBX"
            elif [[ "$ACT" == "discard" ]]; then
                printf 'if header :contains "%s" "%s" { discard; stop; }\n' "$HDR" "$CONT"
            fi
        done
        printf '\n'

        # Vacation
        VAC_MSG="$(echo "$INPUT" | jq -r '.rules[]? | select(.type=="vacation") | .message // ""' | head -n1)"
        if [[ -n "$VAC_MSG" ]]; then
            VAC_SUBJ="$(echo "$INPUT" | jq -r '.rules[]? | select(.type=="vacation") | .subject // "Otomatik yanıt"' | head -n1)"
            VAC_DAYS="$(echo "$INPUT" | jq -r '.rules[]? | select(.type=="vacation") | .days // 7'    | head -n1)"
            printf '# --- Vacation responder ---\n'
            printf 'vacation :days %s :subject "%s" "%s";\n\n' "$VAC_DAYS" "$VAC_SUBJ" "$VAC_MSG"
        fi

        # BoxTrapper: whitelist dışındakileri Quarantine'e
        if [[ "$BOXTRAPPER" == "true" ]]; then
            printf '# --- BoxTrapper (whitelist outside -> Quarantine) ---\n'
            # whitelist JSON dizisini Sieve string list'e çevir
            WL_LIST="$(echo "$INPUT" | jq -r '[.rules[]? | select(.type=="whitelist") | .sender] | map("\"" + . + "\"") | join(", ")')"
            if [[ -n "$WL_LIST" && "$WL_LIST" != "null" ]]; then
                printf 'if not envelope :is "from" [%s] {\n' "$WL_LIST"
                printf '    fileinto "Quarantine";\n'
                printf '    stop;\n'
                printf '}\n'
            else
                printf '# No whitelist defined — boxtrapper disabled.\n'
            fi
        fi
    } > "$SIEVE_TMP"
fi

# Aktive et
install -o vmail -g vmail -m 0600 "$SIEVE_TMP" "$SIEVE_FILE"
BYTES="$(wc -c < "$SIEVE_FILE" | tr -d ' ')"

# doveadm sieve put + compile
if command -v doveadm >/dev/null 2>&1; then
    doveadm sieve put -u "$EMAIL" "managesieve" < "$SIEVE_FILE" 2>/dev/null || true
    doveadm sieve activate -u "$EMAIL" "managesieve" 2>/dev/null || true
fi

onx_audit "onx-sieve" "wrote ${SIEVE_FILE} (${BYTES} bytes) for ${EMAIL}"

cat <<EOF
{"ok":true,"script_path":"${SIEVE_FILE}","bytes":${BYTES},"message":"Sieve script kaydedildi ve aktif edildi"}
EOF
