#!/usr/bin/env bash
# onx-rspamd-test — Bir mail içeriğini Rspamd'a gönderip skor + sembol breakdown alır.
#
# Production worker: `rspamc symbols` (HTTP Controller API'sine ihtiyaç duymaz,
# milter daemon /run/rspamd/rspamd.sock'a doğrudan bağlanır).
#
# stdin: {"message":"<RFC822 full mail content>"}
# stdout: {
#   "action": "no_action|greylist|add_header|rewrite_subject|reject",
#   "score": 4.32,
#   "required_score": 15.0,
#   "symbols": [{"name":"BAYES_SPAM","score":2.1,"description":"..."}],
#   "subject": "Test",
#   "is_skipped": false,
#   "message_id": "<...>"
# }

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

require_root
require_cmd rspamc
require_cmd jq

onx_json_input

MSG=$(echo "$INPUT" | jq -r '.message // empty')
if [[ -z "$MSG" ]]; then
    onx_die 1 "Geçersiz girdi: 'message' alanı boş"
fi

# Çok büyük mesajları reddet — 5 MB üst limit (Rspamd max_message_size'dan bağımsız hız freni)
MSG_LEN=${#MSG}
if [[ "$MSG_LEN" -gt 5242880 ]]; then
    onx_die 1 "Mesaj çok büyük: ${MSG_LEN} bayt (max 5 MB)"
fi

# Mesajı bir tmpfile'a yaz — stdin chain bazen büyük gövdelerde sıkıntı yapar
TMP_EML=$(mktemp -t onx-rspamd-test.XXXXXX.eml)
chmod 600 "$TMP_EML"
trap '[[ -n "${TMP_EML:-}" ]] && rm -f "$TMP_EML" 2>/dev/null || true' EXIT

# RFC 822 başlık eksikse minimal "From:" "To:" "Subject:" ekle — Rspamd parser
# yine de gövdeyi okur, ama bazı sembol kontrolleri (DKIM/SPF) header gerektirir.
if ! echo "$MSG" | head -20 | grep -qiE '^(from|to|subject):'; then
    {
        printf 'From: test@localhost\n'
        printf 'To: postmaster@localhost\n'
        printf 'Subject: Onoxsoft Spam Test\n'
        printf 'Date: %s\n' "$(date -R)"
        printf '\n'
        printf '%s\n' "$MSG"
    } > "$TMP_EML"
else
    printf '%s\n' "$MSG" > "$TMP_EML"
fi

# rspamc çağır — JSON formatlı output al
# --json bayrak rspamc 1.x'te `-j` veya `--json` olabilir; ikisi de destekleniyor.
if ! RSPAMC_OUT=$(rspamc --json symbols < "$TMP_EML" 2>/dev/null); then
    onx_die 3 "rspamc symbols çağrısı başarısız (Rspamd çalışıyor mu?)"
fi

# rspamc bazen başında "[" sonunda "]" wrap ederek array döner; bazen tek obje
# döner. İlk objeyi al.
PARSED=$(echo "$RSPAMC_OUT" | jq -c 'if type == "array" then .[0] else . end' 2>/dev/null || echo '{}')

ACTION=$(echo "$PARSED" | jq -r '.action // "no_action"')
SCORE=$(echo "$PARSED" | jq -r '.score // 0')
REQ_SCORE=$(echo "$PARSED" | jq -r '.required_score // 15')
IS_SKIPPED=$(echo "$PARSED" | jq -r '.is_skipped // false')
SUBJECT=$(echo "$PARSED" | jq -r '.subject // ""')
MSG_ID=$(echo "$PARSED" | jq -r '."message-id" // .messageid // ""')

# Sembol listesini düzleştir — Rspamd map döner: {"BAYES_SPAM":{"score":2.1,...}}
SYMBOLS_JSON=$(echo "$PARSED" | jq -c '
    (.symbols // {}) | to_entries | map({
        name: .key,
        score: (.value.score // 0),
        description: (.value.description // ""),
        options: (.value.options // [])
    }) | sort_by(-.score)
' 2>/dev/null || echo '[]')

# Final JSON output
jq -n \
    --arg action "$ACTION" \
    --argjson score "$SCORE" \
    --argjson req "$REQ_SCORE" \
    --argjson skipped "$IS_SKIPPED" \
    --arg subject "$SUBJECT" \
    --arg msgid "$MSG_ID" \
    --argjson symbols "$SYMBOLS_JSON" \
    '{
        action: $action,
        score: $score,
        required_score: $req,
        is_skipped: $skipped,
        subject: $subject,
        message_id: $msgid,
        symbols: $symbols,
        symbols_count: ($symbols | length)
    }'
