#!/usr/bin/env bash
# =============================================================================
# onx-db-slow-config — Slow query runtime değişkenlerini ROOT olarak uygula (v3.69)
#
# SORUN: Panel app user'ı (onoxsoft_panel) yalnız `USAGE` + kendi DB'sinde `ALL`
#   yetkisine sahip; SUPER/SYSTEM_VARIABLES_ADMIN YOK. Bu yüzden controller'ın
#   `DB::statement("SET GLOBAL slow_query_log=ON")` çağrısı "Access denied" ile
#   sessizce ölüyor → log hiç aktifleşmiyor ("devre dışı" kalıyor).
#
# ÇÖZÜM: SET GLOBAL'i mysql_exec_root (/root/.onox-mysql-root.cnf — SUPER) ile
#   çalıştır → anında aktif, restart GEREKMEZ. Ayrıca kalıcılık için ayrı bir
#   include dosyası (/etc/my.cnf.d/zz-onox-slowquery.cnf) yaz → MySQL restart
#   sonrası da korunur (zz- prefix = en son okunur, diğer include'ları override eder).
#
# Input (stdin JSON — hepsi opsiyonel, sadece verilenler uygulanır):
#   {
#     "slow_query_log":                0|1,      -- OFF/ON
#     "long_query_time":               2,        -- saniye (float, >=0)
#     "log_queries_not_using_indexes": 0|1,      -- OFF/ON
#     "persist":                       true      -- my.cnf include yaz (default true)
#   }
#
# Output (stdout JSON):
#   {"ok":true,"applied":{...},"errors":{...},"current":{...},"persisted":"<path>|null"}
#
# Exit: 0=ok (kısmi hata olsa da çıktıda errors), 1=invalid-input, 2=preflight
#
# Sudoers: apache ALL=(root) NOPASSWD: /usr/local/onoxsoft/bin/onx-db-slow-config
# =============================================================================

set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=_lib/common.sh
source "${SCRIPT_DIR}/_lib/common.sh"
set +e
# nounset KAPALI: APPLIED/ERRORS associative array'leri boşken "${!ERRORS[@]}" /
# ${#ERRORS[@]} expansion'ı bazı bash sürümlerinde "unbound variable" ile patlıyor.
# Bu script nounset'e güvenmiyor; kapatmak JSON çıktı assemble'ını güvenceye alır.
set +u

require_root
require_cmd mysql
onx_json_input

PERSIST="$(onx_json_get_bool "$INPUT" "persist" "true")"

declare -A APPLIED
declare -A ERRORS

# apply_global NAME VALUE — SET GLOBAL'i root ile uygula, sonucu APPLIED/ERRORS'a yaz.
apply_global() {
    local name="$1" value="$2" out rc
    out="$(mysql_exec_root "" "SET GLOBAL ${name} = ${value}" 2>&1)"; rc=$?
    if [[ $rc -eq 0 ]]; then
        APPLIED["$name"]="$value"
    else
        ERRORS["$name"]="$(printf '%s' "$out" | tr '\n' ' ' | head -c 200)"
    fi
}

# ── slow_query_log: 0/1 → OFF/ON ─────────────────────────────────────────────
if echo "$INPUT" | jq -e 'has("slow_query_log")' >/dev/null 2>&1; then
    v="$(onx_json_field slow_query_log '')"
    case "$v" in
        1) apply_global "slow_query_log" "ON" ;;
        0) apply_global "slow_query_log" "OFF" ;;
        *) ERRORS["slow_query_log"]="invalid value: ${v}" ;;
    esac
fi

# ── long_query_time: float >= 0 ──────────────────────────────────────────────
if echo "$INPUT" | jq -e 'has("long_query_time")' >/dev/null 2>&1; then
    v="$(onx_json_field long_query_time '')"
    if [[ "$v" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
        apply_global "long_query_time" "$v"
    else
        ERRORS["long_query_time"]="invalid value: ${v}"
    fi
fi

# ── log_queries_not_using_indexes: 0/1 → OFF/ON ──────────────────────────────
if echo "$INPUT" | jq -e 'has("log_queries_not_using_indexes")' >/dev/null 2>&1; then
    v="$(onx_json_field log_queries_not_using_indexes '')"
    case "$v" in
        1) apply_global "log_queries_not_using_indexes" "ON" ;;
        0) apply_global "log_queries_not_using_indexes" "OFF" ;;
        *) ERRORS["log_queries_not_using_indexes"]="invalid value: ${v}" ;;
    esac
fi

# ── Read back current runtime state (4 var) ──────────────────────────────────
# NOT: mysql_exec_root --batch --silent çıktısında header satırı (Variable_name\tValue)
# bulunabilir → jq'da .[0]=="Variable_name" olanı filtrele (header'lı/header'sız ikisi de OK).
CURRENT_JSON="$(mysql_exec_root "" \
    "SHOW GLOBAL VARIABLES WHERE Variable_name IN ('slow_query_log','long_query_time','log_queries_not_using_indexes','slow_query_log_file')" \
    2>/dev/null | jq -R -s 'split("\n")
        | map(select(length>0) | split("\t")
              | select((.[0] // "") != "Variable_name")
              | {(.[0]): (.[1] // "")})
        | add // {}')"
[[ -z "$CURRENT_JSON" ]] && CURRENT_JSON="{}"

# ── Persist: dedicated my.cnf include (zz- prefix → en son okunur, override eder) ──
PERSISTED="null"
if [[ "$PERSIST" == "true" ]]; then
    INC_DIR=""
    if [[ -d /etc/my.cnf.d ]]; then
        INC_DIR="/etc/my.cnf.d"
    elif [[ -d /etc/mysql/mariadb.conf.d ]]; then
        INC_DIR="/etc/mysql/mariadb.conf.d"
    fi
    if [[ -n "$INC_DIR" ]]; then
        INC_PATH="${INC_DIR}/zz-onox-slowquery.cnf"
        # current runtime'dan değerleri al (uygulama sonrası — kanonik)
        cur_sql="$(echo "$CURRENT_JSON"   | jq -r '.slow_query_log // "OFF"')"
        cur_lqt="$(echo "$CURRENT_JSON"   | jq -r '.long_query_time // "10"')"
        cur_lqni="$(echo "$CURRENT_JSON"  | jq -r '.log_queries_not_using_indexes // "OFF"')"
        cur_file="$(echo "$CURRENT_JSON"  | jq -r '.slow_query_log_file // "panel-slow.log"')"
        # ON/OFF → 1/0 (my.cnf boolean)
        sql_bool=$([[ "${cur_sql^^}" == "ON" ]] && echo 1 || echo 0)
        lqni_bool=$([[ "${cur_lqni^^}" == "ON" ]] && echo 1 || echo 0)
        tmp_inc="$(mktemp -t onx-slowcnf-XXXXXX)"
        {
            printf '# ONOX-managed — onx-db-slow-config tarafından yazıldı. Elle düzenlemeyin.\n'
            printf '[mysqld]\n'
            printf 'slow_query_log = %s\n' "$sql_bool"
            printf 'slow_query_log_file = %s\n' "$cur_file"
            printf 'long_query_time = %s\n' "$cur_lqt"
            printf 'log_queries_not_using_indexes = %s\n' "$lqni_bool"
        } > "$tmp_inc"
        if install -m 0644 -o root -g root "$tmp_inc" "$INC_PATH" 2>/dev/null \
           || { cp -f "$tmp_inc" "$INC_PATH" && chmod 0644 "$INC_PATH"; }; then
            PERSISTED="$INC_PATH"
        fi
        rm -f "$tmp_inc" 2>/dev/null || true
    fi
fi

# ── Build applied/errors JSON (boş array guard'lı — nounset-safe) ────────────
applied_json="{}"
if (( ${#APPLIED[@]} > 0 )); then
    for k in "${!APPLIED[@]}"; do
        applied_json="$(echo "$applied_json" | jq -c --arg k "$k" --arg v "${APPLIED[$k]}" '. + {($k): $v}')"
    done
fi
errors_json="{}"
err_count=0
if (( ${#ERRORS[@]} > 0 )); then
    err_count=${#ERRORS[@]}
    for k in "${!ERRORS[@]}"; do
        errors_json="$(echo "$errors_json" | jq -c --arg k "$k" --arg v "${ERRORS[$k]}" '. + {($k): $v}')"
    done
fi

OK_FLAG=$([[ ${err_count} -eq 0 ]] && echo true || echo false)

onx_log "db-slow-config applied=${applied_json} errors=${errors_json} persisted=${PERSISTED}"

jq -nc \
    --argjson ok "$OK_FLAG" \
    --argjson applied "$applied_json" \
    --argjson errors "$errors_json" \
    --argjson current "$CURRENT_JSON" \
    --arg persisted "$PERSISTED" \
    '{ok:$ok, applied:$applied, errors:$errors, current:$current,
      persisted:(if $persisted=="null" then null else $persisted end)}'
exit 0
