#!/usr/bin/env bash
# onx-cron-audit-read — gerçek sistem + kullanıcı cron'larını yapılandırılmış JSON döner.
# input:  {} veya {"scope":"system|user|all"}   (vsy all)
# output: {"system":[...],"user":[...]}  her kayıt: {source,file,schedule,command,run_as,enabled,managed,account,raw}
source "$(dirname "$(readlink -f "$0")")/_lib/common.sh"
require_root
onx_json_input
SCOPE="$(onx_json_field scope 'all')"

# Bir cron satırını JSON nesnesine çevir. Argümanlar: source file managed owner <satır> sixfield(0/1)
emit_line() {
    local src="$1" file="$2" managed="$3" owner="$4" raw="$5" sixfield="$6"
    local line enabled=true
    raw="${raw%$'\r'}"          # CRLF dosyalarındaki trailing CR'ı at
    line="$raw"
    if [[ "$line" =~ ^[[:space:]]*# ]]; then
        # Yorum satırları yalnız panel-yönetimli + spool dosyalarda "pasif cron" sayılır.
        # Yabancı salt-okunur dosyalarda (/etc/crontab, /etc/cron.d/0hourly vb.) dokümantasyon
        # yorumlarını gösterme — aksi halde "# * * * * * user-name command" örneği sahte cron olur.
        [[ "$managed" == "true" || "$src" == "spool" ]] || return 0
        local stripped="${line#"${line%%[!#[:space:]]*}"}"
        stripped="${stripped#\#}"; stripped="${stripped#"${stripped%%[!#[:space:]]*}"}"
        [[ "$stripped" =~ ^([0-9*@]) ]] || return 0
        line="$stripped"; enabled=false
    fi
    [[ -z "${line// }" ]] && return 0
    [[ "$line" =~ ^[A-Z_]+= ]] && return 0
    local sched cmd run_as account="$owner"
    if [[ "$line" =~ ^@ ]]; then
        sched="$(awk '{print $1}' <<<"$line")"
        if [[ "$sixfield" == "1" ]]; then run_as="$(awk '{print $2}' <<<"$line")"; cmd="$(cut -d' ' -f3- <<<"$line")"; account="$run_as"
        else run_as="$owner"; cmd="$(cut -d' ' -f2- <<<"$line")"; fi
    else
        sched="$(awk '{print $1,$2,$3,$4,$5}' <<<"$line")"
        if [[ "$sixfield" == "1" ]]; then run_as="$(awk '{print $6}' <<<"$line")"; cmd="$(cut -d' ' -f7- <<<"$line")"; account="$run_as"
        else run_as="$owner"; cmd="$(cut -d' ' -f6- <<<"$line")"; fi
    fi
    [[ -z "${cmd// }" ]] && return 0
    jq -nc --arg s "$src" --arg f "$file" --arg sc "$sched" --arg c "$cmd" \
        --arg r "$run_as" --argjson en "$enabled" --argjson mg "$managed" \
        --arg ac "$account" --arg raw "$raw" \
        '{source:$s,file:$f,schedule:$sc,command:$c,run_as:$r,enabled:$en,managed:$mg,account:$ac,raw:$raw}'
}

SYS_OUT=""; USER_OUT=""

read_system() {
    local out=""
    if crontab -l -u root >/dev/null 2>&1; then
        while IFS= read -r l; do out+="$(emit_line 'root-crontab' '/var/spool/cron/root' false root "$l" 0)"$'\n'; done < <(crontab -l -u root 2>/dev/null)
    fi
    if [[ -f /etc/crontab ]]; then
        while IFS= read -r l; do out+="$(emit_line 'etc-crontab' '/etc/crontab' false '' "$l" 1)"$'\n'; done < /etc/crontab
    fi
    local f mg
    for f in /etc/cron.d/*; do
        [[ -f "$f" ]] || continue
        case "$(basename "$f")" in onoxsoft-onx_*) continue ;; onoxsoft-system) mg=true ;; *) mg=false ;; esac
        while IFS= read -r l; do out+="$(emit_line 'cron.d' "$f" "$mg" '' "$l" 1)"$'\n'; done < "$f"
    done
    printf '%s' "$out" | jq -sc '[ .[] | select(.!=null) ]'
}

read_user() {
    local out="" f u
    for f in /var/spool/cron/onx_*; do
        [[ -f "$f" ]] || continue
        u="$(basename "$f")"
        while IFS= read -r l; do out+="$(emit_line 'spool' "$f" false "$u" "$l" 0)"$'\n'; done < "$f"
    done
    for f in /etc/cron.d/onoxsoft-onx_*; do
        [[ -f "$f" ]] || continue
        while IFS= read -r l; do out+="$(emit_line 'cron.d' "$f" true '' "$l" 1)"$'\n'; done < "$f"
    done
    printf '%s' "$out" | jq -sc '[ .[] | select(.!=null) ]'
}

[[ "$SCOPE" == "user" ]] || SYS_OUT="$(read_system)"
[[ "$SCOPE" == "system" ]] || USER_OUT="$(read_user)"
[[ -n "$SYS_OUT" ]] || SYS_OUT='[]'
[[ -n "$USER_OUT" ]] || USER_OUT='[]'

jq -nc --argjson sys "$SYS_OUT" --argjson usr "$USER_OUT" '{system:$sys, user:$usr}'
