#!/usr/bin/env bash
# =============================================================================
# onx-quota-check — Query current XFS quota usage for an account
#
# Purpose:
#   Parses repquota output to retrieve current disk usage and quota limits
#   for a hosting account. Returns usage in MiB with percentage.
#
# Input (stdin JSON):
#   {
#     "username": "onx_xxxx"
#   }
#
# Output (stdout JSON):
#   {
#     "username":    ...,
#     "used_mb":     ...,
#     "soft_mb":     ...,
#     "hard_mb":     ...,
#     "files_used":  ...,
#     "pct":         ...    -- (used_mb / soft_mb * 100), 0 if no quota set
#   }
#
# Exit codes: 0=ok 1=invalid-input 2=preflight-fail 3=exec-fail 4=rolled-back 5=rollback-failed
#
# Sudoers entry needed:
#   apache ALL=(root) NOPASSWD: /usr/local/onoxsoft/bin/onx-quota-check
#   Defaults!/usr/local/onoxsoft/bin/onx-quota-check !requiretty
#   Defaults!/usr/local/onoxsoft/bin/onx-quota-check log_output, log_input
#
# Deployed to: /usr/local/onoxsoft/bin/onx-quota-check
# =============================================================================

set -euo pipefail

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

# ── Dependencies ──────────────────────────────────────────────────────────────
command -v jq       >/dev/null 2>&1 || { printf '{"error":"jq required"}\n' >&2; exit 2; }
command -v repquota >/dev/null 2>&1 || { printf '{"error":"repquota required"}\n' >&2; exit 2; }
require_root

# ── Read & parse stdin ────────────────────────────────────────────────────────
INPUT=$(cat)
onx_require_json "${INPUT}"

USERNAME=$(onx_json_get "${INPUT}" "username")

# ── Input validation ──────────────────────────────────────────────────────────
onx_validate_username "${USERNAME}"

# ── Preflight ─────────────────────────────────────────────────────────────────
id "${USERNAME}" &>/dev/null || onx_die 2 "Linux user does not exist: ${USERNAME}"
mountpoint -q /home           || onx_die 2 "/home is not a mount point (XFS quota requires a separate mount)"

# ── Parse repquota output ─────────────────────────────────────────────────────
# repquota -u /home produces lines like:
#   onx_demo01 --   512    1024   2048         0      100  110
#   Fields (1-indexed, space-separated, after username):
#   [state] used_kb soft_kb hard_kb grace files_used inodes_soft inodes_hard
#
# We use awk to extract just our user's line.
REPQUOTA_LINE=$(repquota -u /home 2>/dev/null | awk -v u="${USERNAME}" '$1 == u {print}')

if [[ -z "${REPQUOTA_LINE}" ]]; then
    # User exists but has no quota entry — output zeroes
    onx_json_out \
        "username"   "${USERNAME}" \
        "used_mb"    "0" \
        "soft_mb"    "0" \
        "hard_mb"    "0" \
        "files_used" "0" \
        "pct"        "0"
    exit 0
fi

# Extract values with awk (skip username + state flag columns)
USED_KB=$(echo  "${REPQUOTA_LINE}" | awk '{print $3}')
SOFT_KB=$(echo  "${REPQUOTA_LINE}" | awk '{print $4}')
HARD_KB=$(echo  "${REPQUOTA_LINE}" | awk '{print $5}')
FILES=$(echo    "${REPQUOTA_LINE}" | awk '{print $7}')

# Convert KiB → MiB (integer division)
USED_MB=$(( USED_KB / 1024 ))
SOFT_MB=$(( SOFT_KB / 1024 ))
HARD_MB=$(( HARD_KB / 1024 ))

# Percentage: avoid div-by-zero; use awk for float
if (( SOFT_KB > 0 )); then
    PCT=$(awk -v u="${USED_KB}" -v s="${SOFT_KB}" \
        'BEGIN { printf "%.2f", (u / s) * 100 }')
else
    PCT="0"
fi

onx_log "quota-check: ${USERNAME} used=${USED_MB}MB soft=${SOFT_MB}MB hard=${HARD_MB}MB pct=${PCT}%"

# ── Output ────────────────────────────────────────────────────────────────────
onx_json_out \
    "username"   "${USERNAME}" \
    "used_mb"    "${USED_MB}" \
    "soft_mb"    "${SOFT_MB}" \
    "hard_mb"    "${HARD_MB}" \
    "files_used" "${FILES}" \
    "pct"        "${PCT}"
