#!/usr/bin/env bash
# =============================================================================
# onx-backup-list — Enumerate backup archives under a directory
#
# Purpose:
#   Scans a directory (default /var/backups/onoxsoft) for *.tar.gz files,
#   extracts metadata (size, mtime, checksum if .sha256 exists), and parses
#   the username from the filename convention `<username>-<timestamp>.tar.gz`.
#
# Input (stdin JSON):
#   {
#     "account_id": 1,                              -- optional; filter
#     "username":   "onx_acme01",                   -- optional; filter
#     "path":       "/var/backups/onoxsoft"         -- default
#   }
#
# Output (stdout JSON):
#   {
#     "total": 5,
#     "path":  "/var/backups/onoxsoft",
#     "backups": [
#       {
#         "filename":    "onx_acme01-20260514120000.tar.gz",
#         "full_path":   "/var/backups/onoxsoft/onx_acme01-20260514120000.tar.gz",
#         "size_bytes":  N,
#         "created_at":  "2026-05-14T12:00:00Z",
#         "sha256":      "..." | null,
#         "username":    "onx_acme01"
#       }
#     ]
#   }
#
# Exit codes: 0=ok 1=invalid 2=preflight 3=exec
#
# Deployed to: /usr/local/onoxsoft/bin/onx-backup-list
# =============================================================================

set -euo pipefail

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

readonly BACKUP_ROOT_ALLOWED="/var/backups"
readonly DEFAULT_BACKUP_DIR="/var/backups/onoxsoft"

require_root

onx_json_input

ACCOUNT_ID=$(onx_json_field "account_id" "")
USERNAME_FILTER=$(onx_json_field "username" "")
BACKUP_DIR=$(onx_json_field "path" "${DEFAULT_BACKUP_DIR}")

# ── Validation ───────────────────────────────────────────────────────────────
[[ -z "${BACKUP_DIR}" ]] && BACKUP_DIR="${DEFAULT_BACKUP_DIR}"

BACKUP_DIR_REAL="$(realpath -m "${BACKUP_DIR}" 2>/dev/null || printf '%s' "${BACKUP_DIR}")"
case "${BACKUP_DIR_REAL}" in
    ${BACKUP_ROOT_ALLOWED}|${BACKUP_ROOT_ALLOWED}/*) : ;;
    *) onx_die 1 "path '${BACKUP_DIR}' must be under ${BACKUP_ROOT_ALLOWED}/" ;;
esac

if [[ -n "${USERNAME_FILTER}" ]]; then
    onx_validate_username "${USERNAME_FILTER}"
fi

# Path may not yet exist on a brand-new install; that's not fatal.
if [[ ! -d "${BACKUP_DIR_REAL}" ]]; then
    jq -nc --arg p "${BACKUP_DIR_REAL}" '{total:0, path:$p, backups:[]}'
    exit 0
fi

# ── Enumerate ────────────────────────────────────────────────────────────────
ITEMS=()
TOTAL=0

if [[ "${MOCK_MODE}" == "1" ]]; then
    # 3 sample backups
    for i in 1 2 3; do
        TS_BACK=$(( i * 86400 ))
        CREATED_AT=$(date -u -d "@$(( $(date +%s) - TS_BACK ))" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || date -u +"%Y-%m-%dT%H:%M:%SZ")
        USER_FAKE="${USERNAME_FILTER:-onx_demo$(printf '%02d' "${i}")}"
        FAKE_NAME="${USER_FAKE}-20260514$(printf '%04d' $(( i * 1000 ))).tar.gz"
        FAKE_SIZE=$(( (RANDOM % 400 + 50) * 1024 * 1024 ))
        ITEMS+=("$(jq -nc \
            --arg fn "${FAKE_NAME}" \
            --arg fp "${BACKUP_DIR_REAL}/${FAKE_NAME}" \
            --argjson sz "${FAKE_SIZE}" \
            --arg ca "${CREATED_AT}" \
            --arg sha "$(printf '%064d' $(( RANDOM * RANDOM )) )" \
            --arg user "${USER_FAKE}" \
            '{filename:$fn,full_path:$fp,size_bytes:$sz,created_at:$ca,sha256:$sha,username:$user}')")
        TOTAL=$(( TOTAL + 1 ))
    done
else
    # shopt makes nullglob safe — no expansion when no matches
    shopt -s nullglob
    for f in "${BACKUP_DIR_REAL}"/*.tar.gz; do
        [[ -f "${f}" ]] || continue
        FN="$(basename "${f}")"

        # Username = prefix before the last '-' (e.g. onx_acme01-20260514120000.tar.gz)
        USER_FROM_NAME="${FN%-*}"
        # Strip .tar.gz if no separator was found
        USER_FROM_NAME="${USER_FROM_NAME%.tar.gz}"

        # Filter by username if requested
        if [[ -n "${USERNAME_FILTER}" && "${USER_FROM_NAME}" != "${USERNAME_FILTER}" ]]; then
            continue
        fi

        SIZE=$(stat -c '%s' "${f}" 2>/dev/null || echo 0)
        MTIME=$(stat -c '%Y' "${f}" 2>/dev/null || echo 0)
        CREATED_AT=$(date -u -d "@${MTIME}" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "")

        # Pull sha256 from sidecar; null if missing
        SHA="null"
        if [[ -f "${f}.sha256" ]]; then
            S=$(awk '{print $1}' "${f}.sha256" 2>/dev/null)
            [[ -n "${S}" ]] && SHA="\"${S}\""
        fi

        ITEMS+=("$(jq -nc \
            --arg fn "${FN}" \
            --arg fp "${f}" \
            --argjson sz "${SIZE}" \
            --arg ca "${CREATED_AT}" \
            --argjson sha "${SHA}" \
            --arg user "${USER_FROM_NAME}" \
            '{filename:$fn,full_path:$fp,size_bytes:$sz,created_at:$ca,sha256:$sha,username:$user}')")
        TOTAL=$(( TOTAL + 1 ))
    done
    shopt -u nullglob
fi

# Sort by created_at desc and emit
if [[ ${#ITEMS[@]} -gt 0 ]]; then
    LIST=$(printf '%s\n' "${ITEMS[@]}" | jq -s 'sort_by(.created_at) | reverse')
else
    LIST="[]"
fi

jq -nc \
    --argjson total "${TOTAL}" \
    --arg path "${BACKUP_DIR_REAL}" \
    --argjson backups "${LIST}" \
    '{total:$total, path:$path, backups:$backups}'
