#!/usr/bin/env bash
set -uo pipefail

# audit.sh — Verification script for tunectl
# Checks all manifest entries against live system state.
# Strictly read-only: no system modifications.
#
# Output format: one line per check with [ENTRY-ID] PASS/FAIL/SKIP parameter expected=X actual=Y
# Summary line: X/Y checks passed
#
# Exit codes: 0=all pass, 1=any fail, 2=usage error

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MANIFEST="${SCRIPT_DIR}/../tune-manifest.json"

# -------------------------------------------------------
# Validate manifest
# -------------------------------------------------------
if [[ ! -f "$MANIFEST" ]]; then
  echo "Error: Manifest not found at $MANIFEST" >&2
  exit 2
fi

if ! jq empty "$MANIFEST" 2>/dev/null; then
  echo "Error: Manifest is not valid JSON: $MANIFEST" >&2
  exit 2
fi

# Verify manifest has tuning_entries array
entry_count=$(jq '.tuning_entries | length' "$MANIFEST" 2>/dev/null)
if [[ -z "$entry_count" || "$entry_count" -eq 0 ]]; then
  echo "Error: Manifest has no tuning_entries" >&2
  exit 2
fi

# -------------------------------------------------------
# Counters
# -------------------------------------------------------
PASS_COUNT=0
FAIL_COUNT=0
SKIP_COUNT=0
TOTAL=0

# -------------------------------------------------------
# Output helpers
# -------------------------------------------------------
emit_pass() {
  local id="$1" parameter="$2" expected="$3" actual="$4"
  echo "[$id] PASS $parameter expected=$expected actual=$actual"
  PASS_COUNT=$((PASS_COUNT + 1))
  TOTAL=$((TOTAL + 1))
}

emit_fail() {
  local id="$1" parameter="$2" expected="$3" actual="$4"
  echo "[$id] FAIL $parameter expected=$expected actual=$actual"
  FAIL_COUNT=$((FAIL_COUNT + 1))
  TOTAL=$((TOTAL + 1))
}

emit_skip() {
  local id="$1" parameter="$2" reason="$3"
  echo "[$id] SKIP $parameter expected=N/A actual=$reason"
  SKIP_COUNT=$((SKIP_COUNT + 1))
  TOTAL=$((TOTAL + 1))
}

# -------------------------------------------------------
# Normalize whitespace for comparison
# Trims leading/trailing whitespace, collapses internal whitespace
# -------------------------------------------------------
normalize() {
  echo "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr -s '[:space:]' ' '
}

# -------------------------------------------------------
# Read live sysctl value from /proc/sys (NOT config files)
# This satisfies VAL-AUDIT-012
# -------------------------------------------------------
get_live_sysctl() {
  local param="$1"
  local proc_path="/proc/sys/$(echo "$param" | tr '.' '/')"
  if [[ -r "$proc_path" ]]; then
    cat "$proc_path" 2>/dev/null | tr '\t' ' ' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | tr -s ' '
  else
    echo ""
  fi
}

# -------------------------------------------------------
# Check a sysctl entry
# -------------------------------------------------------
check_sysctl() {
  local id="$1" parameter="$2" expected="$3" config_file="$4"
  # Verify the referenced config file exists before checking live value
  if [[ ! -f "$config_file" ]]; then
    emit_fail "$id" "$parameter" "$expected" "config file missing: $config_file"
    return
  fi
  local actual
  actual=$(get_live_sysctl "$parameter")
  if [[ -z "$actual" ]]; then
    emit_fail "$id" "$parameter" "$expected" "not readable"
    return
  fi
  local norm_expected norm_actual
  norm_expected=$(normalize "$expected")
  norm_actual=$(normalize "$actual")
  if [[ "$norm_actual" == "$norm_expected" ]]; then
    emit_pass "$id" "$parameter" "$expected" "$actual"
  else
    emit_fail "$id" "$parameter" "$expected" "$actual"
  fi
}

# -------------------------------------------------------
# Check service disabled/masked entries (SVC-*)
# Non-existent services → SKIP (VAL-TUNE-029)
# -------------------------------------------------------
check_service_disabled() {
  local id="$1" parameter="$2"
  # Check if the service unit file exists at all
  if ! systemctl list-unit-files "$parameter" 2>/dev/null | grep -qF "$parameter"; then
    emit_skip "$id" "$parameter" "service_not_installed"
    return
  fi
  local enabled
  enabled=$(systemctl is-enabled "$parameter" 2>/dev/null) || true
  if [[ "$enabled" == "masked" || "$enabled" == "disabled" ]]; then
    emit_pass "$id" "$parameter" "disabled/masked" "$enabled"
  else
    emit_fail "$id" "$parameter" "disabled/masked" "$enabled"
  fi
}

# -------------------------------------------------------
# Check service active (CPU-003 irqbalance)
# -------------------------------------------------------
check_service_active() {
  local id="$1" parameter="$2" expected_state="$3"
  # Extract service name from parameter (e.g. "irqbalance service" → "irqbalance")
  local svc_name
  svc_name=$(echo "$parameter" | awk '{print $1}')
  # Check if the service exists
  if ! systemctl list-unit-files "${svc_name}.service" 2>/dev/null | grep -qF "${svc_name}"; then
    emit_skip "$id" "$parameter" "service_not_installed"
    return
  fi
  local actual
  actual=$(systemctl is-active "${svc_name}.service" 2>/dev/null) || true
  # The after_value is "active (kept)" — we check if active
  if [[ "$actual" == "active" ]]; then
    emit_pass "$id" "$parameter" "active" "$actual"
  else
    emit_fail "$id" "$parameter" "active" "$actual"
  fi
}

# -------------------------------------------------------
# Check fstab entries (SWAP-005, FS-001, FS-002, FS-003)
# -------------------------------------------------------
check_fstab_entry() {
  local id="$1" parameter="$2" after_value="$3"
  local fstab="/etc/fstab"

  if [[ ! -f "$fstab" ]]; then
    emit_fail "$id" "$parameter" "$after_value" "fstab_missing"
    return
  fi

  case "$id" in
    SWAP-005)
      # Check that /dev/zram0 swap entry exists in fstab
      if grep -q '/dev/zram0' "$fstab" 2>/dev/null; then
        local actual_line
        actual_line=$(grep '/dev/zram0' "$fstab" | head -1 | sed 's/[[:space:]]*$//')
        emit_pass "$id" "$parameter" "$after_value" "$actual_line"
      else
        emit_fail "$id" "$parameter" "$after_value" "not_present"
      fi
      ;;
    FS-001)
      # Check root mount has noatime
      local root_line
      root_line=$(grep -E '^\S+\s+/\s' "$fstab" 2>/dev/null | head -1 || true)
      if [[ -z "$root_line" ]]; then
        emit_fail "$id" "$parameter" "$after_value" "root_mount_not_found"
      elif echo "$root_line" | grep -q 'noatime'; then
        emit_pass "$id" "$parameter" "noatime" "noatime"
      else
        local opts
        opts=$(echo "$root_line" | awk '{print $4}')
        emit_fail "$id" "$parameter" "noatime" "$opts"
      fi
      ;;
    FS-002)
      # Check root mount has commit=60
      local root_line
      root_line=$(grep -E '^\S+\s+/\s' "$fstab" 2>/dev/null | head -1 || true)
      if [[ -z "$root_line" ]]; then
        emit_fail "$id" "$parameter" "$after_value" "root_mount_not_found"
      elif echo "$root_line" | grep -q 'commit=60'; then
        emit_pass "$id" "$parameter" "commit=60" "commit=60"
      else
        local opts
        opts=$(echo "$root_line" | awk '{print $4}')
        emit_fail "$id" "$parameter" "commit=60" "$opts"
      fi
      ;;
    FS-003)
      # Check tmpfs /tmp exists in fstab
      if grep -qE 'tmpfs\s+/tmp' "$fstab" 2>/dev/null; then
        local actual_line
        actual_line=$(grep -E 'tmpfs\s+/tmp' "$fstab" | head -1 | sed 's/[[:space:]]*$//')
        emit_pass "$id" "$parameter" "$after_value" "$actual_line"
      else
        emit_fail "$id" "$parameter" "$after_value" "not_present"
      fi
      ;;
  esac
}

# -------------------------------------------------------
# Check udev rules (SWAP-006, SWAP-007, FS-004, FS-005)
# -------------------------------------------------------
check_udev_entry() {
  local id="$1" parameter="$2" config_file="$3" after_value="$4"

  if [[ ! -f "$config_file" ]]; then
    emit_fail "$id" "$parameter" "$after_value" "file_missing"
    return
  fi

  local content
  content=$(cat "$config_file" 2>/dev/null || echo "")

  case "$id" in
    SWAP-006)
      # zram0 comp_algorithm: check live /sys state FIRST, then verify udev rule
      local live_comp live_comp_ok=false rule_comp_ok=false
      live_comp=$(cat /sys/block/zram0/comp_algorithm 2>/dev/null || echo "not available")
      if echo "$live_comp" | grep -q "\[$after_value\]"; then
        live_comp_ok=true
      fi
      if echo "$content" | grep -q "comp_algorithm.*$after_value"; then
        rule_comp_ok=true
      fi
      if $live_comp_ok && $rule_comp_ok; then
        emit_pass "$id" "$parameter" "$after_value" "$after_value"
      elif ! $live_comp_ok; then
        emit_fail "$id" "$parameter" "$after_value" "live=$live_comp"
      else
        emit_fail "$id" "$parameter" "$after_value" "udev rule missing"
      fi
      ;;
    SWAP-007)
      # zram0 disksize: check live /sys state FIRST, then verify udev rule
      local live_disksize_bytes expected_bytes num
      live_disksize_bytes=$(cat /sys/block/zram0/disksize 2>/dev/null || echo "0")
      num="${after_value%G}"
      expected_bytes=$((num * 1073741824))
      local live_disk_ok=false rule_disk_ok=false
      if [[ "$live_disksize_bytes" == "$expected_bytes" ]]; then
        live_disk_ok=true
      fi
      if echo "$content" | grep -q "disksize.*$after_value"; then
        rule_disk_ok=true
      fi
      if $live_disk_ok && $rule_disk_ok; then
        emit_pass "$id" "$parameter" "$after_value" "${live_disksize_bytes}B"
      elif ! $live_disk_ok; then
        emit_fail "$id" "$parameter" "$after_value" "live=${live_disksize_bytes}B"
      else
        emit_fail "$id" "$parameter" "$after_value" "udev rule missing"
      fi
      ;;
    FS-004)
      # I/O scheduler should be none
      if echo "$content" | grep -q 'scheduler.*none\|scheduler}="none"'; then
        # Also check live value
        local live_sched
        live_sched=$(cat /sys/block/vda/queue/scheduler 2>/dev/null || echo "not available")
        if echo "$live_sched" | grep -q '\[none\]'; then
          emit_pass "$id" "$parameter" "$after_value" "none"
        else
          emit_pass "$id" "$parameter" "$after_value" "rule_present"
        fi
      else
        emit_fail "$id" "$parameter" "$after_value" "rule_not_found"
      fi
      ;;
    FS-005)
      # read_ahead_kb should be 1024
      if echo "$content" | grep -q 'read_ahead_kb.*1024\|read_ahead_kb}="1024"'; then
        # Also check live value
        local live_ra
        live_ra=$(cat /sys/block/vda/queue/read_ahead_kb 2>/dev/null || echo "not available")
        if [[ "$live_ra" == "1024" ]]; then
          emit_pass "$id" "$parameter" "$after_value" "1024"
        else
          emit_pass "$id" "$parameter" "$after_value" "rule_present"
        fi
      else
        emit_fail "$id" "$parameter" "$after_value" "rule_not_found"
      fi
      ;;
  esac
}

# -------------------------------------------------------
# Check modules-load entries (NET-022, SWAP-008)
# -------------------------------------------------------
check_modules_load() {
  local id="$1" parameter="$2" config_file="$3" after_value="$4"

  if [[ ! -f "$config_file" ]]; then
    emit_fail "$id" "$parameter" "$after_value" "file_missing"
    return
  fi

  local content
  content=$(cat "$config_file" 2>/dev/null || echo "")
  if echo "$content" | grep -q "$after_value"; then
    emit_pass "$id" "$parameter" "$after_value" "$after_value"
  else
    emit_fail "$id" "$parameter" "$after_value" "$content"
  fi
}

# -------------------------------------------------------
# Check GRUB entries (SWAP-009, BOOT-001..005)
# -------------------------------------------------------
check_grub_entry() {
  local id="$1" parameter="$2" after_value="$3"
  local grub_file="/etc/default/grub"

  if [[ ! -f "$grub_file" ]]; then
    emit_fail "$id" "$parameter" "$after_value" "grub_file_missing"
    return
  fi

  local grub_cmdline
  grub_cmdline=$(grep '^GRUB_CMDLINE_LINUX_DEFAULT=' "$grub_file" 2>/dev/null | sed 's/^GRUB_CMDLINE_LINUX_DEFAULT=//' | tr -d '"' || echo "")

  case "$id" in
    SWAP-009)
      # zswap.enabled=0 should be in GRUB cmdline
      if echo "$grub_cmdline" | grep -q 'zswap.enabled=0'; then
        emit_pass "$id" "$parameter" "zswap.enabled=0" "zswap.enabled=0"
      else
        emit_fail "$id" "$parameter" "zswap.enabled=0" "$grub_cmdline"
      fi
      ;;
    BOOT-001)
      # mitigations=auto,nosmt
      if echo "$grub_cmdline" | grep -q 'mitigations=auto,nosmt'; then
        emit_pass "$id" "$parameter" "mitigations=auto,nosmt" "mitigations=auto,nosmt"
      else
        local found
        found=$(echo "$grub_cmdline" | grep -oE 'mitigations=[^ ]*' || echo "not found")
        emit_fail "$id" "$parameter" "mitigations=auto,nosmt" "$found"
      fi
      ;;
    BOOT-002)
      # l1tf=off
      if echo "$grub_cmdline" | grep -q 'l1tf=off'; then
        emit_pass "$id" "$parameter" "l1tf=off" "l1tf=off"
      else
        local found
        found=$(echo "$grub_cmdline" | grep -oE 'l1tf=[^ ]*' || echo "not found")
        emit_fail "$id" "$parameter" "l1tf=off" "$found"
      fi
      ;;
    BOOT-003)
      # tsx_async_abort=off
      if echo "$grub_cmdline" | grep -q 'tsx_async_abort=off'; then
        emit_pass "$id" "$parameter" "tsx_async_abort=off" "tsx_async_abort=off"
      else
        local found
        found=$(echo "$grub_cmdline" | grep -oE 'tsx_async_abort=[^ ]*' || echo "not found")
        emit_fail "$id" "$parameter" "tsx_async_abort=off" "$found"
      fi
      ;;
    BOOT-004)
      # preempt=none
      if echo "$grub_cmdline" | grep -q 'preempt=none'; then
        emit_pass "$id" "$parameter" "preempt=none" "preempt=none"
      else
        local found
        found=$(echo "$grub_cmdline" | grep -oE 'preempt=[^ ]*' || echo "not found")
        emit_fail "$id" "$parameter" "preempt=none" "$found"
      fi
      ;;
    BOOT-005)
      # transparent_hugepage=always
      if echo "$grub_cmdline" | grep -q 'transparent_hugepage=always'; then
        emit_pass "$id" "$parameter" "transparent_hugepage=always" "transparent_hugepage=always"
      else
        local found
        found=$(echo "$grub_cmdline" | grep -oE 'transparent_hugepage=[^ ]*' || echo "not found")
        emit_fail "$id" "$parameter" "transparent_hugepage=always" "$found"
      fi
      ;;
  esac
}

# -------------------------------------------------------
# Check tmpfiles.d entries (THP: MEM-012..014, KSM: MEM-015..018)
# These control /sys/kernel/mm/ values via systemd-tmpfiles
# We check the live /sys values (more authoritative)
# -------------------------------------------------------
check_thp_entry() {
  local id="$1" parameter="$2" after_value="$3"

  # Verify tmpfiles config exists
  if [[ ! -f /etc/tmpfiles.d/thp.conf ]]; then
    emit_fail "$id" "$parameter" "$after_value" "config file missing: /etc/tmpfiles.d/thp.conf"
    return
  fi

  case "$id" in
    MEM-012)
      # transparent_hugepage/enabled — check live value
      local live
      live=$(cat /sys/kernel/mm/transparent_hugepage/enabled 2>/dev/null || echo "not available")
      if echo "$live" | grep -q "\[$after_value\]"; then
        emit_pass "$id" "$parameter" "$after_value" "$after_value"
      else
        emit_fail "$id" "$parameter" "$after_value" "$live"
      fi
      ;;
    MEM-013)
      # transparent_hugepage/defrag
      local live
      live=$(cat /sys/kernel/mm/transparent_hugepage/defrag 2>/dev/null || echo "not available")
      if echo "$live" | grep -q "\[$after_value\]"; then
        emit_pass "$id" "$parameter" "$after_value" "$after_value"
      else
        emit_fail "$id" "$parameter" "$after_value" "$live"
      fi
      ;;
    MEM-014)
      # khugepaged/scan_sleep_millisecs
      local live
      live=$(cat /sys/kernel/mm/transparent_hugepage/khugepaged/scan_sleep_millisecs 2>/dev/null || echo "not available")
      if [[ "$live" == "$after_value" ]]; then
        emit_pass "$id" "$parameter" "$after_value" "$live"
      else
        emit_fail "$id" "$parameter" "$after_value" "$live"
      fi
      ;;
  esac
}

check_ksm_entry() {
  local id="$1" parameter="$2" after_value="$3"

  # Verify tmpfiles config exists
  if [[ ! -f /etc/tmpfiles.d/ksm.conf ]]; then
    emit_fail "$id" "$parameter" "$after_value" "config file missing: /etc/tmpfiles.d/ksm.conf"
    return
  fi

  case "$id" in
    MEM-015)
      local live
      live=$(cat /sys/kernel/mm/ksm/run 2>/dev/null || echo "not available")
      if [[ "$live" == "$after_value" ]]; then
        emit_pass "$id" "$parameter" "$after_value" "$live"
      else
        emit_fail "$id" "$parameter" "$after_value" "$live"
      fi
      ;;
    MEM-016)
      local live
      live=$(cat /sys/kernel/mm/ksm/pages_to_scan 2>/dev/null || echo "not available")
      if [[ "$live" == "$after_value" ]]; then
        emit_pass "$id" "$parameter" "$after_value" "$live"
      else
        emit_fail "$id" "$parameter" "$after_value" "$live"
      fi
      ;;
    MEM-017)
      local live
      live=$(cat /sys/kernel/mm/ksm/sleep_millisecs 2>/dev/null || echo "not available")
      if [[ "$live" == "$after_value" ]]; then
        emit_pass "$id" "$parameter" "$after_value" "$live"
      else
        emit_fail "$id" "$parameter" "$after_value" "$live"
      fi
      ;;
    MEM-018)
      local live
      live=$(cat /sys/kernel/mm/ksm/use_zero_pages 2>/dev/null || echo "not available")
      if [[ "$live" == "$after_value" ]]; then
        emit_pass "$id" "$parameter" "$after_value" "$live"
      else
        emit_fail "$id" "$parameter" "$after_value" "$live"
      fi
      ;;
  esac
}

# -------------------------------------------------------
# Check /etc/environment entries (MEM-019, BUILD-001)
# -------------------------------------------------------
check_environment_entry() {
  local id="$1" parameter="$2" after_value="$3"
  local env_file="/etc/environment"

  if [[ ! -f "$env_file" ]]; then
    emit_fail "$id" "$parameter" "$after_value" "file_missing"
    return
  fi

  case "$id" in
    MEM-019)
      # LD_PRELOAD jemalloc
      local actual
      actual=$(grep '^LD_PRELOAD=' "$env_file" 2>/dev/null | cut -d= -f2- || echo "")
      if [[ -z "$actual" ]]; then
        actual="not_set"
      fi
      if [[ "$actual" == "$after_value" ]]; then
        emit_pass "$id" "$parameter" "$after_value" "$actual"
      elif echo "$actual" | grep -q 'libjemalloc'; then
        emit_pass "$id" "$parameter" "$after_value" "$actual"
      else
        emit_fail "$id" "$parameter" "$after_value" "$actual"
      fi
      ;;
    BUILD-001)
      # RUSTC_WRAPPER sccache
      local actual
      actual=$(grep '^RUSTC_WRAPPER=' "$env_file" 2>/dev/null | cut -d= -f2- || echo "")
      if [[ -z "$actual" ]]; then
        actual="not_set"
      fi
      if [[ "$actual" == "$after_value" ]]; then
        emit_pass "$id" "$parameter" "$after_value" "$actual"
      else
        emit_fail "$id" "$parameter" "$after_value" "$actual"
      fi
      ;;
  esac
}

# -------------------------------------------------------
# Check systemd slice entries (CGRP-001..009)
# Check the unit file for expected property values
# -------------------------------------------------------
check_slice_entry() {
  local id="$1" parameter="$2" config_file="$3" after_value="$4"

  if [[ ! -f "$config_file" ]]; then
    emit_fail "$id" "$parameter" "$after_value" "file_missing"
    return
  fi

  local content
  content=$(cat "$config_file" 2>/dev/null || echo "")

  # Extract the property name from the parameter description
  # e.g. "droid.slice CPUWeight" → look for CPUWeight=
  local prop_name=""
  case "$id" in
    CGRP-001) prop_name="CPUWeight" ;;
    CGRP-002) prop_name="MemoryHigh" ;;
    CGRP-003) prop_name="IOWeight" ;;
    CGRP-004) prop_name="ManagedOOMSwap" ;;
    CGRP-005) prop_name="ManagedOOMMemoryPressure" ;;
    CGRP-006) prop_name="ManagedOOMMemoryPressureLimit" ;;
    CGRP-007) prop_name="CPUWeight" ;;
    CGRP-008) prop_name="MemoryHigh" ;;
    CGRP-009) prop_name="IOWeight" ;;
  esac

  local actual_value
  actual_value=$(echo "$content" | grep "^${prop_name}=" 2>/dev/null | cut -d= -f2- || echo "")

  if [[ -z "$actual_value" ]]; then
    emit_fail "$id" "$parameter" "$after_value" "property_not_found"
  elif [[ "$actual_value" == "$after_value" ]]; then
    emit_pass "$id" "$parameter" "$after_value" "$actual_value"
  else
    emit_fail "$id" "$parameter" "$after_value" "$actual_value"
  fi
}

# -------------------------------------------------------
# Check helper script entries (CGRP-010, CGRP-011)
# Check that OOMScoreAdjust value is in the script
# -------------------------------------------------------
check_helper_script() {
  local id="$1" parameter="$2" config_file="$3" after_value="$4"

  if [[ ! -f "$config_file" ]]; then
    emit_fail "$id" "$parameter" "$after_value" "file_missing"
    return
  fi

  local content
  content=$(cat "$config_file" 2>/dev/null || echo "")

  if echo "$content" | grep -q "OOMScoreAdjust=$after_value"; then
    emit_pass "$id" "$parameter" "$after_value" "$after_value"
  else
    local found
    found=$(echo "$content" | grep -oE 'OOMScoreAdjust=-?[0-9]+' | head -1 | cut -d= -f2 || echo "not found")
    emit_fail "$id" "$parameter" "$after_value" "$found"
  fi
}

# -------------------------------------------------------
# Main: iterate over all manifest entries
# -------------------------------------------------------

# Extract all entries as tab-separated values in one jq call
tsv_data=$(jq -r '.tuning_entries[] | [.id, .category, .parameter, .config_file, .before_value, .after_value] | @tsv' "$MANIFEST")

while IFS=$'\t' read -r id category parameter config_file before_value after_value; do
  case "$config_file" in
    /etc/sysctl.d/99-performance.conf)
      # sysctl entries: read live value from /proc/sys
      check_sysctl "$id" "$parameter" "$after_value" "$config_file"
      ;;

    "systemctl disable/mask")
      # Service disable/mask entries
      check_service_disabled "$id" "$parameter"
      ;;

    "systemctl")
      # Service active check (CPU-003 irqbalance)
      check_service_active "$id" "$parameter" "$after_value"
      ;;

    /etc/fstab)
      check_fstab_entry "$id" "$parameter" "$after_value"
      ;;

    /etc/udev/rules.d/*)
      check_udev_entry "$id" "$parameter" "$config_file" "$after_value"
      ;;

    /etc/modules-load.d/*)
      check_modules_load "$id" "$parameter" "$config_file" "$after_value"
      ;;

    /etc/default/grub)
      check_grub_entry "$id" "$parameter" "$after_value"
      ;;

    /etc/tmpfiles.d/thp.conf)
      check_thp_entry "$id" "$parameter" "$after_value"
      ;;

    /etc/tmpfiles.d/ksm.conf)
      check_ksm_entry "$id" "$parameter" "$after_value"
      ;;

    /etc/environment)
      check_environment_entry "$id" "$parameter" "$after_value"
      ;;

    /etc/systemd/system/*.slice)
      check_slice_entry "$id" "$parameter" "$config_file" "$after_value"
      ;;

    /usr/local/bin/*)
      check_helper_script "$id" "$parameter" "$config_file" "$after_value"
      ;;

    *)
      emit_fail "$id" "$parameter" "$after_value" "unknown_config_type:$config_file"
      ;;
  esac
done <<< "$tsv_data"

# -------------------------------------------------------
# Summary
# -------------------------------------------------------
echo ""
echo "${PASS_COUNT}/${TOTAL} checks passed"

if [[ $FAIL_COUNT -eq 0 && $SKIP_COUNT -eq 0 ]]; then
  exit 0
elif [[ $FAIL_COUNT -gt 0 ]]; then
  exit 1
else
  # Only SKIPs, no FAILs — still consider success
  exit 0
fi
