#!/usr/bin/env bash
# onx-postqueue-status — parse `postqueue -p` ve `mailq` çıktısı; JSON döner.
#
# stdin: {"filter":"deferred|active|hold|all"}  (filter opsiyonel, default "all")
# stdout:
#   {
#     "ok": true,
#     "count": 12,
#     "totals": {"queue_size": 12, "active": 3, "deferred": 7, "hold": 2, "bytes": 1238456},
#     "queue": [
#        {"queue_id":"A1B2C3","size":4218,"arrival":"Fri May 15 09:12:33",
#         "sender":"foo@x.tr","recipient":"bar@y.com","reason":"…","status":"deferred"},
#        …
#     ]
#   }
#
# Notlar:
# - Postfix "mailq" / "postqueue -p" çıktısı; queue id sonunda "*" = active,
#   "!" = hold, hiçbiri = deferred. Recipient(ler) bir sonraki satırlarda;
#   "(...)" parantez içinde gecikme sebebi.
# - filter == "all" ise hiçbir filtre uygulanmaz.

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

require_root
require_cmd postqueue

INPUT="$(cat || true)"
FILTER="all"
if [[ -n "$INPUT" ]]; then
    FILTER="$(echo "$INPUT" | jq -r '.filter // "all"')"
fi
case "$FILTER" in all|deferred|active|hold) : ;; *) FILTER="all" ;; esac

RAW="$(postqueue -p 2>/dev/null || true)"

if [[ -z "$RAW" || "$RAW" == "Mail queue is empty" ]]; then
    printf '{"ok":true,"count":0,"filter":"%s","totals":{"queue_size":0,"active":0,"deferred":0,"hold":0,"bytes":0},"queue":[]}\n' "$FILTER"
    exit 0
fi

# awk: postqueue -p formatı satır 1 header, son satır toplam.
# Her entry 2+ satır: 1. queue_id size arrival sender  (sonraki satırlarda recipient/reason)
ENTRIES_JSON="$(printf '%s\n' "$RAW" | awk -v FILTER="$FILTER" '
    function jsonesc(s,    r) {
        r = s
        gsub(/\\/, "\\\\", r)
        gsub(/"/,  "\\\"", r)
        gsub(/\n/, "\\n",  r)
        gsub(/\r/, "",     r)
        gsub(/\t/, " ",    r)
        return r
    }
    function flush(   recs, rec, st) {
        if (qid == "") return
        st = "deferred"
        if (mark == "*") st = "active"
        else if (mark == "!") st = "hold"
        if (FILTER != "all" && FILTER != st) { reset(); return }
        rec = "{"
        rec = rec "\"queue_id\":\"" jsonesc(qid) "\","
        rec = rec "\"size\":" (size+0) ","
        rec = rec "\"arrival\":\"" jsonesc(arrival) "\","
        rec = rec "\"sender\":\"" jsonesc(sender) "\","
        rec = rec "\"recipient\":\"" jsonesc(recipient) "\","
        rec = rec "\"reason\":\"" jsonesc(reason) "\","
        rec = rec "\"status\":\"" st "\""
        rec = rec "}"
        if (out != "") out = out ","
        out = out rec
        counts[st]++
        total_bytes += (size+0)
        total_count++
        reset()
    }
    function reset() { qid=""; mark=""; size=0; arrival=""; sender=""; recipient=""; reason="" }
    BEGIN { reset(); out="" }
    /^-Queue ID/ { next }
    /^---/ { next }
    /^[[:space:]]*$/ { flush(); next }
    /^-- [0-9]+ Kbytes in [0-9]+/ { flush(); next }
    {
        if ($1 ~ /^[A-Fa-f0-9]+[\*!]?$/) {
            flush()
            qid = $1
            mark = ""
            if (qid ~ /\*$/) { mark = "*"; sub(/\*$/, "", qid) }
            else if (qid ~ /!$/) { mark = "!"; sub(/!$/, "", qid) }
            size = $2
            arrival = $3 " " $4 " " $5 " " $6 " " $7
            sender = $8
            recipient = ""
            reason = ""
            next
        }
        line = $0
        sub(/^[[:space:]]+/, "", line)
        if (line ~ /^\(.*\)$/) {
            r = line
            sub(/^\(/, "", r); sub(/\)$/, "", r)
            reason = (reason == "" ? r : reason " | " r)
        } else {
            recipient = (recipient == "" ? line : recipient ", " line)
        }
    }
    END {
        flush()
        printf "{\"entries\":[%s],\"counts\":{\"active\":%d,\"deferred\":%d,\"hold\":%d},\"total_count\":%d,\"total_bytes\":%d}",
            out, counts["active"]+0, counts["deferred"]+0, counts["hold"]+0, total_count+0, total_bytes+0
    }
')"

# Tek bir json'a paketle
echo "$ENTRIES_JSON" | jq --arg f "$FILTER" '{
    ok: true,
    count: .total_count,
    filter: $f,
    totals: {
        queue_size: .total_count,
        active: .counts.active,
        deferred: .counts.deferred,
        hold: .counts.hold,
        bytes: .total_bytes
    },
    queue: .entries
}'
