#!/usr/bin/env bash
# onx-cron-edit — panel-yönetilebilir cron dosyalarını düzenle.
# Aksiyonlar (action):
#   system-add    {minute,hour,day,month,weekday,command,run_as?}  → /etc/cron.d/onoxsoft-system'e ekle
#   system-delete {raw}                                            → onoxsoft-system'de tam satırı sil
#   system-toggle {raw}                                            → onoxsoft-system'de satırı yorumla/aç
#   user-toggle   {file,raw}                                       → allowlist'li user dosyasında satırı yorumla/aç
source "$(dirname "$(readlink -f "$0")")/_lib/common.sh"
require_root
onx_json_input
ACTION="$(onx_json_field action '')"
SYS_FILE="/etc/cron.d/onoxsoft-system"

validate_field() { [[ "$1" =~ ^[0-9*/,A-Za-z-]+$ ]] || onx_die 1 "geçersiz cron alanı: $2 ('$1')"; }
reload_cron() { systemctl reload-or-restart cronie 2>/dev/null || systemctl reload-or-restart crond 2>/dev/null || systemctl reload-or-restart cron 2>/dev/null || true; }

ensure_sys_header() {
    [[ -f "$SYS_FILE" ]] && return 0
    { printf '# Onoxsoft managed system crons — panelden yönetilir\n';
      printf 'SHELL=/bin/bash\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n\n'; } > "$SYS_FILE"
    chown root:root "$SYS_FILE"; chmod 0644 "$SYS_FILE"
}

assert_user_file() {
    local f="$1" rp
    case "$f" in /var/spool/cron/onx_*|/etc/cron.d/onoxsoft-onx_*) : ;; *) onx_die 1 "izin verilmeyen dosya: $f" ;; esac
    rp="$(realpath -e -- "$f" 2>/dev/null)" || onx_die 2 "dosya yok: $f"
    case "$rp" in /var/spool/cron/onx_*|/etc/cron.d/onoxsoft-onx_*) : ;; *) onx_die 1 "izin verilmeyen dosya (resolved): $rp" ;; esac
    printf '%s' "$rp"
}

# file raw mode(delete|toggle): tam-eşleşen satırı sil veya yorumla/aç (CRLF toleranslı).
edit_line() {
    local file="$1" raw="$2" mode="$3" tmp found=0 l
    tmp="$(mktemp)"; trap 'rm -f "$tmp"' RETURN
    while IFS= read -r l || [[ -n "$l" ]]; do
        l="${l%$'\r'}"
        if [[ "$l" == "$raw" ]]; then
            found=1; [[ "$mode" == "delete" ]] && continue; printf '# %s\n' "$l" >> "$tmp"
        elif [[ "$l" == "# $raw" || "$l" == "#$raw" ]]; then
            found=1; [[ "$mode" == "delete" ]] && continue; printf '%s\n' "$raw" >> "$tmp"
        else
            printf '%s\n' "$l" >> "$tmp"
        fi
    done < "$file"
    [[ "$found" == "1" ]] || onx_die 2 "satır bulunamadı"
    chmod 0644 "$tmp"; mv -f "$tmp" "$file"; chown root:root "$file"
}

case "$ACTION" in
  system-add)
    MIN="$(onx_json_field minute)"; HOUR="$(onx_json_field hour)"; DAY="$(onx_json_field day)"
    MON="$(onx_json_field month)"; WD="$(onx_json_field weekday)"; CMD="$(onx_json_field command)"
    RUN_AS="$(onx_json_field run_as 'root')"
    validate_field "$MIN" minute; validate_field "$HOUR" hour; validate_field "$DAY" day
    validate_field "$MON" month; validate_field "$WD" weekday
    [[ -n "$CMD" ]] || onx_die 1 "command gerekli"
    [[ "$CMD" == *$'\n'* ]] && onx_die 1 "command newline içeremez"
    getent passwd "$RUN_AS" >/dev/null 2>&1 || onx_die 1 "geçersiz çalışan kullanıcı: $RUN_AS"
    ensure_sys_header
    printf '%s %s %s %s %s %s %s\n' "$MIN" "$HOUR" "$DAY" "$MON" "$WD" "$RUN_AS" "$CMD" >> "$SYS_FILE"
    onx_audit "onx-cron" "system-add run_as=$RUN_AS cmd=$CMD"; reload_cron
    onx_json_out ok true action system-add ;;
  system-delete)
    RAW="$(onx_json_field raw)"; [[ -n "$RAW" ]] || onx_die 1 "raw gerekli"; [[ -f "$SYS_FILE" ]] || onx_die 2 "dosya yok"
    edit_line "$SYS_FILE" "$RAW" delete; onx_audit "onx-cron" "system-delete raw=$RAW"; reload_cron
    onx_json_out ok true action system-delete ;;
  system-toggle)
    RAW="$(onx_json_field raw)"; [[ -n "$RAW" ]] || onx_die 1 "raw gerekli"; [[ -f "$SYS_FILE" ]] || onx_die 2 "dosya yok"
    edit_line "$SYS_FILE" "$RAW" toggle; onx_audit "onx-cron" "system-toggle raw=$RAW"; reload_cron
    onx_json_out ok true action system-toggle ;;
  user-toggle)
    F="$(onx_json_field file)"; RAW="$(onx_json_field raw)"; [[ -n "$F" && -n "$RAW" ]] || onx_die 1 "file+raw gerekli"
    RF="$(assert_user_file "$F")"; edit_line "$RF" "$RAW" toggle; onx_audit "onx-cron" "user-toggle file=$RF"; reload_cron
    onx_json_out ok true action user-toggle ;;
  *) onx_die 1 "bilinmeyen action: $ACTION" ;;
esac
