#!/usr/bin/env bash
# =============================================================================
# onx-mailbox-disk-usage — Report per-mailbox disk metrics
#
# Input (stdin JSON):
#   {"email":"user@example.com"}
#
# Output (stdout JSON):
#   {
#     "email":       "...",
#     "maildir":     "/var/vmail/.../Maildir",
#     "bytes":       19283744,
#     "cur_bytes":   18000000,
#     "new_bytes":   1000000,
#     "tmp_bytes":   283744,
#     "messages":    432,
#     "quota_bytes": 1073741824,
#     "quota_mb":    1024,
#     "usage_pct":   1.79
#   }
#
# Exit codes: 0=ok 1=invalid 2=preflight 3=exec
#
# Deployed to: /usr/local/onoxsoft/bin/onx-mailbox-disk-usage
# =============================================================================

set -euo pipefail

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

require_root
if [[ "${MOCK_MODE}" != "1" ]]; then
    command -v mysql >/dev/null 2>&1 || onx_die 2 "mysql client not found"
fi

onx_json_input

EMAIL_RAW=$(onx_json_field "email")
onx_validate_email "${EMAIL_RAW}" >/dev/null
EMAIL="${ONX_EMAIL}"
LOCAL="${ONX_EMAIL_LOCAL}"
DOMAIN="${ONX_EMAIL_DOMAIN}"

MAILBOX_HOME="/var/vmail/${DOMAIN}/${LOCAL}"
MAILDIR="${MAILBOX_HOME}/Maildir"
onx_validate_vmail_path "${MAILBOX_HOME}" >/dev/null

# ── Pull quota from DB ───────────────────────────────────────────────────────
QUOTA_BYTES=$(mysql_exec "${DOVECOT_DB_NAME}" \
    "SELECT quota_bytes FROM dovecot_users WHERE email='${EMAIL}';" 2>/dev/null | tail -1)
QUOTA_BYTES="${QUOTA_BYTES:-0}"
[[ "${QUOTA_BYTES}" =~ ^-?[0-9]+$ ]] || QUOTA_BYTES=0

if [[ "${QUOTA_BYTES}" -gt 0 ]]; then
    QUOTA_MB=$(( QUOTA_BYTES / 1024 / 1024 ))
else
    QUOTA_MB=-1
fi

# ── Compute disk metrics ─────────────────────────────────────────────────────
# Missing Maildir is not fatal — it just means zero usage (e.g. account
# created in DB but never delivered to yet).
BYTES=0
CUR_BYTES=0
NEW_BYTES=0
TMP_BYTES=0
MESSAGES=0

_du_bytes() {
    local p="$1"
    if [[ -d "$p" ]]; then
        du -sb "$p" 2>/dev/null | awk '{print $1}'
    else
        printf '0'
    fi
}

if [[ -d "${MAILDIR}" ]]; then
    BYTES=$(_du_bytes "${MAILDIR}")
    CUR_BYTES=$(_du_bytes "${MAILDIR}/cur")
    NEW_BYTES=$(_du_bytes "${MAILDIR}/new")
    TMP_BYTES=$(_du_bytes "${MAILDIR}/tmp")
    # Count delivered messages. Maildir filenames have at least one comma or
    # colon (info field) and live under cur/ or new/.
    MESSAGES=$(find "${MAILDIR}/cur" "${MAILDIR}/new" -maxdepth 1 -type f 2>/dev/null | wc -l)
fi

BYTES="${BYTES:-0}"
CUR_BYTES="${CUR_BYTES:-0}"
NEW_BYTES="${NEW_BYTES:-0}"
TMP_BYTES="${TMP_BYTES:-0}"
MESSAGES="${MESSAGES:-0}"

# ── Compute usage % (two decimals) ───────────────────────────────────────────
USAGE_PCT="0.00"
if [[ "${QUOTA_BYTES}" -gt 0 ]]; then
    USAGE_PCT=$(awk -v b="${BYTES}" -v q="${QUOTA_BYTES}" 'BEGIN { printf "%.2f", (b / q) * 100 }')
fi

# Compose JSON via jq so floats and ints don't get mangled.
jq -nc \
    --arg email      "${EMAIL}" \
    --arg maildir    "${MAILDIR}" \
    --argjson bytes      "${BYTES}" \
    --argjson cur        "${CUR_BYTES}" \
    --argjson new_b      "${NEW_BYTES}" \
    --argjson tmp_b      "${TMP_BYTES}" \
    --argjson messages   "${MESSAGES}" \
    --argjson quota_b    "${QUOTA_BYTES}" \
    --argjson quota_mb   "${QUOTA_MB}" \
    --argjson usage_pct  "${USAGE_PCT}" \
    '{
       email: $email,
       maildir: $maildir,
       bytes: $bytes,
       cur_bytes: $cur,
       new_bytes: $new_b,
       tmp_bytes: $tmp_b,
       messages: $messages,
       quota_bytes: $quota_b,
       quota_mb: $quota_mb,
       usage_pct: $usage_pct
     }'
