#!/bin/bash
# Simple TidalCycles Performance Optimizer
# This script optimizes an existing TidalCycles setup for performance

# Set variables
SAVED_CPU_GOVERNOR="/tmp/saved_cpu_governor.txt"
SAVED_EPP="/tmp/saved_cpu_epp.txt"
SAVED_MAX_PCT="/tmp/saved_cpu_max_pct.txt"
# Peak-clock cap for --cool (percent of max). 85% still shaves the sustained
# turbo spikes that drive thermal-throttle events, but leaves enough ceiling for
# the editor's bursty UI work to clear quickly. Tune with COOL_MAX_PCT=NN
# (lower = cooler but laggier UI; higher = snappier but warmer).
COOL_MAX_PCT="${COOL_MAX_PCT:-85}"

# Display help
show_help() {
  echo "Simple TidalCycles Performance Optimizer"
  echo ""
  echo "Usage: $0 [option]"
  echo ""
  echo "Options:"
  echo "  --optimize    Apply standard performance optimizations to running processes"
  echo "  --extreme     Apply extreme performance optimizations (for live performance)"
  echo "  --cool        Thermal-aware mode: fix audio RT priorities + cap peak clock"
  echo "                (heatwave / fanless-feel; keeps audio snappy without cooking the CPU)"
  echo "  --stop        Reset system to normal operation"
  echo "  --check       Check current system load and running processes"
  echo "  --diagnose    Run diagnostics to investigate audio stutters"
  echo "  --help        Show this help message"
  echo ""
  echo "Example: $0 --extreme"
  echo ""
  echo "IMPORTANT: Launch your applications (SuperCollider, Ardour, OBS, etc.) FIRST,"
  echo "then run this script to optimize performance."
}

# Check if running as root
check_root() {
  if [ "$EUID" -ne 0 ]; then
    echo "This script requires root permissions."
    echo "Please run with sudo: sudo $0 $1"
    exit 1
  fi
}

# Check system load before making changes
check_system_load() {
  echo "=== CURRENT SYSTEM LOAD ==="
  echo ""
  echo "Top CPU-consuming processes:"
  ps aux --sort=-%cpu | head -15
  echo ""
  echo "Memory usage:"
  free -h
  echo ""
  echo "Real-time priorities (FIFO/RR):"
  ps -eLo rtprio,cls,pid,pri,nice,cmd | grep -v " - " | head -20
  echo ""
  echo "I/O priorities:"
  for pid in $(ps -eo pid --sort=-%cpu | head -10 | grep -v PID); do
    echo -n "PID $pid ($(ps -p $pid -o comm= 2>/dev/null)): "
    ionice -p $pid 2>/dev/null || echo "Failed to get I/O priority"
  done
  echo ""
  echo "Current CPU governor:"
  cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor | uniq
  echo ""
}

# Run diagnostics to investigate audio stutters
run_diagnostics() {
  check_root "--diagnose"
  
  echo "========================================"
  echo "RUNNING AUDIO STUTTER DIAGNOSTICS"
  echo "========================================"
  
  echo "Looking for potential causes of audio stutters..."
  
  # Check if CPU scaling is causing issues
  echo -e "\n=== CPU SCALING STATUS ==="
  echo "Current CPU governor:"
  cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor | uniq
  
  if [ -f "/sys/devices/system/cpu/intel_pstate/no_turbo" ]; then
    echo "CPU Turbo status (1=disabled, 0=enabled):"
    cat /sys/devices/system/cpu/intel_pstate/no_turbo
  fi
  
  if [ -d "/sys/devices/system/cpu/intel_pstate" ]; then
    echo "Min performance percentage:"
    cat /sys/devices/system/cpu/intel_pstate/min_perf_pct 2>/dev/null
  fi
  
  # Check for excessive disk I/O
  echo -e "\n=== DISK I/O STATUS ==="
  if command -v iostat >/dev/null 2>&1; then
    iostat -x 1 2
  else
    echo "iostat not available. Install sysstat package for disk I/O diagnostics."
  fi
  
  # Check for memory pressure
  echo -e "\n=== MEMORY STATUS ==="
  free -h
  echo "Memory pressure indicators:"
  grep -E "pgpgin|pgpgout|pgmajfault" /proc/vmstat
  
  # Check for active processes
  echo -e "\n=== CHECKING FOR BACKGROUND JOBS ==="
  echo "Recently started tasks:"
  ps -eo start_time,pid,cmd --sort=start_time | tail -n 20
  
  # Check for interrupt conflicts
  echo -e "\n=== INTERRUPT ACTIVITY ==="
  echo "Top 10 interrupts by count:"
  cat /proc/interrupts | head -n 1
  cat /proc/interrupts | sort -k2 -nr | head -n 10
  
  # Check PipeWire status
  echo -e "\n=== PIPEWIRE STATUS ==="
  echo "PipeWire processes:"
  ps -ef | grep pipewire | grep -v grep
  
  # Check for processes with realtime priority
  echo -e "\n=== REALTIME PRIORITY PROCESSES ==="
  ps -eLo rtprio,cls,pid,pri,nice,cmd | grep -v " - " | head -n 15
  
  # Check system uptime and load
  echo -e "\n=== SYSTEM LOAD ==="
  uptime
  
  # Check CPU throttling due to thermal issues
  echo -e "\n=== CPU THERMAL STATUS ==="
  if [ -d /sys/devices/system/cpu/cpu0/thermal_throttle ]; then
    echo "Thermal throttling events (non-zero indicates potential performance issues):"
    cat /sys/devices/system/cpu/cpu*/thermal_throttle/core_throttle_count
  else
    echo "Thermal throttling info not available"
  fi
  
  # Check for powersave settings on USB devices
  echo -e "\n=== USB POWER MANAGEMENT ==="
  echo "USB devices with power management (may cause audio interface dropouts):"
  for usb in /sys/bus/usb/devices/*/power/control; do
    if [ -f "$usb" ]; then
      echo "$usb: $(cat $usb)"
    fi
  done
  
  # Check for system logging activity
  echo -e "\n=== SYSTEM LOGGING ACTIVITY ==="
  echo "Journal activity:"
  journalctl --disk-usage
  
  # Check audio settings
  echo -e "\n=== AUDIO INTERFACE SETTINGS ==="
  echo "PipeWire sample rate and buffer settings:"
  if command -v pw-metadata >/dev/null 2>&1; then
    pw-metadata 0 | grep buffer || echo "No buffer metadata found"
    pw-metadata 0 | grep rate || echo "No rate metadata found"
  else
    echo "pw-metadata not available"
  fi
  
  echo -e "\n=== RECOMMENDATIONS ==="
  echo "Based on the diagnostics, here are some possible causes of audio stutters:"
  echo "1. Check if any thermal throttling is occurring"
  echo "2. Ensure USB power management is disabled for audio interfaces"
  echo "3. Consider increasing buffer size in PipeWire if needed"
  echo "4. Run 'sudo $0 --extreme' before performance to apply maximum optimizations"
}

# Function to apply standard performance optimizations
optimize_standard() {
  check_root "--optimize"
  
  echo "========================================"
  echo "APPLYING STANDARD PERFORMANCE OPTIMIZATIONS"
  echo "========================================"
  
  # Save current CPU governor
  cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor > $SAVED_CPU_GOVERNOR
  
  # Stop non-essential services
  echo "Stopping non-essential services..."
  USER=$(logname || whoami)
  systemctl --user -M $USER@ stop kde-baloo.service 2>/dev/null
  systemctl --user -M $USER@ stop plasma-baloorunner.service 2>/dev/null
  systemctl --user -M $USER@ stop app-geoclue-demo-agent@autostart.service 2>/dev/null
  systemctl --user -M $USER@ stop app-firewall-applet@autostart.service 2>/dev/null
  echo "✓ Non-essential services stopped"
  
  # Set CPU governor to performance
  echo "Setting CPU governor to performance mode..."
  echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
  echo "✓ CPU governor set to performance"
  
  # Keep CPU Turbo ENABLED — see note in optimize_extreme(). Disabling turbo on
  # an HWP CPU caps the clock at base and starves SuperDirt's DSP (causes xruns).
  if [ -f "/sys/devices/system/cpu/intel_pstate/no_turbo" ]; then
    echo "Ensuring CPU Turbo is enabled..."
    echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
    echo "✓ CPU Turbo enabled"
  fi
  
  # Apply IRQ thread priorities
  echo "Setting IRQ thread priorities..."
  for irq in $(find /proc/irq/*/smp_affinity -type f 2>/dev/null | grep -v self); do
    irq_num=$(echo $irq | cut -d '/' -f 4)
    name=$(cat /proc/irq/$irq_num/name 2>/dev/null)
    
    # Check if this is an audio-related IRQ
    if [[ "$name" == *"snd"* ]] || [[ "$name" == *"audio"* ]] || [[ "$name" == *"hda"* ]]; then
      echo "Setting audio IRQ $irq_num ($name) affinity"
      echo 1 > /proc/irq/$irq_num/smp_affinity 2>/dev/null
    fi
  done
  
  # Reduce kernel printk level to minimize logging impact
  echo "Reducing kernel logging level..."
  echo 1 > /proc/sys/kernel/printk
  echo "✓ Kernel logging reduced"
  
  # Set process priorities with standard mode
  set_priorities standard
  
  echo "✅ Standard performance optimizations applied. Your audio should be more stable now."
  echo "To reset when done, run: sudo $0 --stop"
}

# Function to apply extreme performance optimizations
optimize_extreme() {
  check_root "--extreme"
  
  echo "========================================"
  echo "APPLYING EXTREME PERFORMANCE OPTIMIZATIONS"
  echo "========================================"
  
  # Save current CPU governor
  cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor > $SAVED_CPU_GOVERNOR
  
  # Stop more services
  echo "Stopping non-essential services..."
  USER=$(logname || whoami)
  systemctl --user -M $USER@ stop kde-baloo.service 2>/dev/null
  systemctl --user -M $USER@ stop plasma-baloorunner.service 2>/dev/null
  systemctl --user -M $USER@ stop app-geoclue-demo-agent@autostart.service 2>/dev/null
  systemctl --user -M $USER@ stop app-firewall-applet@autostart.service 2>/dev/null
  systemctl --user -M $USER@ stop kaccess.service 2>/dev/null
  systemctl --user -M $USER@ stop plasma-ksystemstats.service 2>/dev/null
  systemctl --user -M $USER@ stop plasma-dolphin.service 2>/dev/null
  echo "✓ Non-essential services stopped"
  
  # Stop system services that can cause stutters
  echo "Stopping potentially interfering system services..."
  systemctl stop packagekit.service 2>/dev/null
  systemctl mask packagekit.service 2>/dev/null
  # Reduce journald rate instead of killing it (need logs if something crashes)
  echo "RateLimitBurst=10" > /run/systemd/journald.conf.d/perf.conf 2>/dev/null || true
  systemctl reload systemd-journald.service 2>/dev/null
  echo "✓ System services stopped/throttled"
  
  # Set CPU governor to performance
  echo "Setting CPU governor to performance mode..."
  echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
  echo "✓ CPU governor set to performance"
  
  # Pin CPU to MAXIMUM sustained clock — turbo ENABLED.
  # NOTE: on HWP-capable CPUs (this i7-10875H has hwp), the performance governor
  # already holds clocks steady at the top and P-state transitions are near-instant.
  # Disabling turbo here used to "avoid frequency-change jitter" but it actually
  # CAPS the CPU at base clock (2.3GHz vs ~4.3GHz turbo) — starving SuperDirt's DSP
  # and causing the very crackling/xruns it was meant to prevent. Keep turbo ON.
  echo "Pinning CPU to max clock (turbo enabled)..."
  if [ -f "/sys/devices/system/cpu/intel_pstate/no_turbo" ]; then
    echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
    echo "✓ CPU Turbo enabled (full clock headroom available)"
  fi
  
  if [ -d "/sys/devices/system/cpu/intel_pstate" ]; then
    echo 100 > /sys/devices/system/cpu/intel_pstate/max_perf_pct 2>/dev/null
    echo 100 > /sys/devices/system/cpu/intel_pstate/min_perf_pct 2>/dev/null
    echo "✓ Intel CPU min/max performance pinned to 100% (no downclocking, turbo reachable)"
  fi
  
  # Disable NMI watchdog (can cause stutters)
  echo "Disabling NMI watchdog..."
  echo 0 > /proc/sys/kernel/nmi_watchdog
  echo "✓ NMI watchdog disabled"
  
  # Apply IRQ thread priorities
  echo "Setting IRQ thread priorities..."
  for irq in $(find /proc/irq/*/smp_affinity -type f 2>/dev/null | grep -v self); do
    irq_num=$(echo $irq | cut -d '/' -f 4)
    name=$(cat /proc/irq/$irq_num/name 2>/dev/null)
    
    # Check if this is an audio-related IRQ
    if [[ "$name" == *"snd"* ]] || [[ "$name" == *"audio"* ]] || [[ "$name" == *"hda"* ]]; then
      echo "Setting audio IRQ $irq_num ($name) affinity"
      echo 1 > /proc/irq/$irq_num/smp_affinity 2>/dev/null
    fi
  done
  
  # Reduce kernel printk level to minimize logging impact
  echo "Reducing kernel logging level (silence non-critical messages)..."
  echo 1 > /proc/sys/kernel/printk
  echo "✓ Kernel logging reduced"
  
  # NOTE: UI process priority is handled in set_priorities() below

  # Disable VM swappiness to prevent swapping during performance
  echo "Reducing swap aggressiveness..."
  echo 1 > /proc/sys/vm/swappiness
  echo "✓ Set swappiness to minimum (1)"
  
  # Set buffer drops to extremely high to prevent buffer underruns
  echo "Setting VM settings for audio performance..."
  echo 20000000 > /proc/sys/vm/dirty_bytes
  echo 40000000 > /proc/sys/vm/dirty_background_bytes
  echo "✓ Set VM buffer parameters for better audio performance"
  
  # Set process priorities with extreme mode
  set_priorities extreme
  
  echo "⚠️ WARNING: UI may be less responsive during extreme performance mode."
  echo "✅ Extreme performance optimizations applied. Your audio should be more stable now."
  echo "To reset when done, run: sudo $0 --stop"
}

# Function to apply THERMAL-AWARE optimizations (heatwave mode)
# Philosophy is the OPPOSITE of --extreme: instead of pinning the CPU to 100%
# (max heat), we cap the peak clock to shave turbo spikes, and lean on proper
# real-time scheduling so the audio chain stays glitch-free at a lower, cooler
# clock. Fixing scsynth's RT priority is what makes the cap free of audio cost.
optimize_cool() {
  check_root "--cool"

  echo "========================================"
  echo "APPLYING THERMAL-AWARE (COOL) OPTIMIZATIONS"
  echo "========================================"

  # Save current state for clean restore
  cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor > $SAVED_CPU_GOVERNOR
  cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference > $SAVED_EPP 2>/dev/null
  cat /sys/devices/system/cpu/intel_pstate/max_perf_pct > $SAVED_MAX_PCT 2>/dev/null

  # Stop the few indexers/updaters that wake the CPU in the background
  echo "Quieting background CPU wakers..."
  USER=$(logname || whoami)
  systemctl --user -M $USER@ stop kde-baloo.service 2>/dev/null
  systemctl --user -M $USER@ stop plasma-baloorunner.service 2>/dev/null
  systemctl stop packagekit.service 2>/dev/null
  echo "✓ Background services quieted"

  # Keep the powersave governor — it idles cool and ramps on demand.
  echo "Setting CPU governor to powersave (cool idle, on-demand ramp)..."
  echo powersave | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
  echo "✓ Governor: powersave"

  # Bias the energy/perf hint to balance_performance: intel_pstate still idles
  # cool, but ramps FAST when there's demand. balance_power was too lazy here —
  # it left the cores at ~2.4GHz even while Pulsar's renderer screamed at 118%,
  # which is exactly the few-hundred-ms UI freezes the editor was showing. This
  # keeps the heat win (idle backoff + the cap below) without starving bursts.
  if [ -f /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference ]; then
    echo balance_performance | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference > /dev/null 2>&1
    echo "✓ EPP: balance_performance (fast ramp, cool idle)"
  fi

  # Cap the PEAK clock instead of pinning it. This is the core heat lever.
  if [ -d /sys/devices/system/cpu/intel_pstate ]; then
    echo "$COOL_MAX_PCT" > /sys/devices/system/cpu/intel_pstate/max_perf_pct 2>/dev/null
    # Leave min low so it still drops to a cool idle between events.
    echo 15 > /sys/devices/system/cpu/intel_pstate/min_perf_pct 2>/dev/null
    # Turbo stays ON but bounded by the cap above — brief headroom, no sustained roast.
    echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo 2>/dev/null
    echo "✓ Peak clock capped to ${COOL_MAX_PCT}% (turbo bounded, idle stays low)"
  fi

  # Light VM tuning: avoid swap-driven stalls during a set without forcing anything.
  echo 10 > /proc/sys/vm/swappiness 2>/dev/null
  echo "✓ Swappiness lowered to 10"

  # The actual lag fix lives here: give the audio chain real RT priority so it
  # stays responsive even at the capped clock. scsynth at FIFO 1 -> 90.
  set_priorities cool

  echo ""
  echo "✅ Cool mode applied."
  echo "   • Audio chain now real-time scheduled (scsynth/sclang/pipewire)."
  echo "   • Peak clock capped at ${COOL_MAX_PCT}% to keep temps down."
  echo "   • Editor/desktop niced so they don't steal cycles from the audio."
  echo "   Re-run with COOL_MAX_PCT=70 ... for more cooling, 90 for more headroom."
  echo "   Reset anytime: sudo $0 --stop"
}

# Function to set process priorities
set_priorities() {
  mode=$1
  echo "Setting process priorities (mode: $mode)..."
  
  # Find SuperCollider processes
  SC_SERVER=$(pgrep scsynth)
  SC_LANG=$(pgrep sclang)
  
  if [ ! -z "$SC_SERVER" ]; then
    # Set realtime priority
    chrt -f -p 90 $SC_SERVER
    # Protect from OOM killer
    echo -17 > /proc/$SC_SERVER/oom_adj 2>/dev/null || echo -1000 > /proc/$SC_SERVER/oom_score_adj 2>/dev/null
    # Lock memory to prevent swapping
    prlimit --pid $SC_SERVER --memlock=unlimited 2>/dev/null
    echo "✓ Set scsynth (PID $SC_SERVER) to real-time FIFO priority 90"
  else
    echo "⚠ scsynth process not found - make sure SuperCollider is running"
  fi
  
  if [ ! -z "$SC_LANG" ]; then
    chrt -f -p 85 $SC_LANG
    echo -17 > /proc/$SC_LANG/oom_adj 2>/dev/null || echo -1000 > /proc/$SC_LANG/oom_score_adj 2>/dev/null
    prlimit --pid $SC_LANG --memlock=unlimited 2>/dev/null
    echo "✓ Set sclang (PID $SC_LANG) to real-time FIFO priority 85"
  else
    echo "⚠ sclang process not found - make sure SuperCollider is running"
  fi
  
  # Find Ardour process and all its children - use more patterns
  ARDOUR=$(pgrep -f "ardour-8|/ardour|ardour8")
  if [ ! -z "$ARDOUR" ]; then
    chrt -f -p 80 $ARDOUR
    ionice -c 1 -n 0 -p $ARDOUR
    echo -17 > /proc/$ARDOUR/oom_adj 2>/dev/null || echo -1000 > /proc/$ARDOUR/oom_score_adj 2>/dev/null
    prlimit --pid $ARDOUR --memlock=unlimited 2>/dev/null
    echo "✓ Set Ardour (PID $ARDOUR) to real-time priority 80"
    
    # Find child processes of Ardour
    for child in $(pgrep -P $ARDOUR); do
      chrt -f -p 79 $child
      ionice -c 1 -n 0 -p $child
      echo "  ✓ Set Ardour child (PID $child) to priority 79"
    done
  else
    echo "ℹ️ Ardour process not found - skipping"
  fi
  
  # Find PipeWire/WirePlumber processes and boost their priority
  PIPEWIRE_PIDS=$(pgrep pipewire)
  if [ ! -z "$PIPEWIRE_PIDS" ]; then
    for PW_PID in $PIPEWIRE_PIDS; do
      chrt -f -p 95 $PW_PID
      echo -17 > /proc/$PW_PID/oom_adj 2>/dev/null || echo -1000 > /proc/$PW_PID/oom_score_adj 2>/dev/null
    done
    echo "✓ Set PipeWire (PID $PIPEWIRE_PIDS) to real-time priority 95"
  fi
  
  WIREPLUMBER_PID=$(pgrep wireplumber)
  if [ ! -z "$WIREPLUMBER_PID" ]; then
    chrt -f -p 95 $WIREPLUMBER_PID
    echo -17 > /proc/$WIREPLUMBER_PID/oom_adj 2>/dev/null || echo -1000 > /proc/$WIREPLUMBER_PID/oom_score_adj 2>/dev/null
    echo "✓ Set WirePlumber (PID $WIREPLUMBER_PID) to real-time priority 95"
  fi
  
  # Find QjackCtl if running
  QJACKCTL_PID=$(pgrep qjackctl)
  if [ ! -z "$QJACKCTL_PID" ]; then
    chrt -f -p 75 $QJACKCTL_PID
    echo "✓ Set QjackCtl (PID $QJACKCTL_PID) to priority 75"
  fi
  
  # Find OBS Studio if running
  OBS_PID=$(pgrep obs)
  if [ ! -z "$OBS_PID" ]; then
    if [ "$mode" != "standard" ]; then
      renice -n 5 -p $OBS_PID
      ionice -c 2 -n 5 -p $OBS_PID
    else
      renice -n 0 -p $OBS_PID
      ionice -c 2 -n 3 -p $OBS_PID
    fi
    echo "✓ Set OBS (PID $OBS_PID) to appropriate priority for $mode mode"
  fi
  
  # Find ASEQ processes
  ASEQ_PID=$(pgrep aseqdump)
  if [ ! -z "$ASEQ_PID" ]; then
    chrt -f -p 80 $ASEQ_PID
    echo "✓ Set aseqdump (PID $ASEQ_PID) to real-time priority 80"
  fi
  
  # Find Pulsar editor processes and set lower priority
  PULSAR_PIDS=$(pgrep -f pulsar)

  # DWIM: if no Pulsar, launch it in the script's directory using the user's session env
  if [ -z "$PULSAR_PIDS" ]; then
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    REF_PID=$(pgrep -u "$USER" -x kwin_wayland | head -1)
    [ -z "$REF_PID" ] && REF_PID=$(pgrep -u "$USER" -x kwin_x11 | head -1)
    [ -z "$REF_PID" ] && REF_PID=$(pgrep -u "$USER" -x plasmashell | head -1)
    if [ -n "$REF_PID" ] && [ -r "/proc/$REF_PID/environ" ]; then
      echo "ℹ️ Pulsar not running — launching in $SCRIPT_DIR..."
      get_env_var() { tr '\0' '\n' < "/proc/$1/environ" | grep "^$2=" | head -1 | cut -d= -f2-; }
      sudo -u "$USER" env \
        DISPLAY="$(get_env_var "$REF_PID" DISPLAY)" \
        WAYLAND_DISPLAY="$(get_env_var "$REF_PID" WAYLAND_DISPLAY)" \
        XDG_RUNTIME_DIR="$(get_env_var "$REF_PID" XDG_RUNTIME_DIR)" \
        DBUS_SESSION_BUS_ADDRESS="$(get_env_var "$REF_PID" DBUS_SESSION_BUS_ADDRESS)" \
        XDG_SESSION_TYPE="$(get_env_var "$REF_PID" XDG_SESSION_TYPE)" \
        nohup pulsar "$SCRIPT_DIR" </dev/null >/dev/null 2>&1 &
      for _ in $(seq 1 20); do
        PULSAR_PIDS=$(pgrep -f pulsar)
        [ -n "$PULSAR_PIDS" ] && break
        sleep 0.5
      done
      if [ -n "$PULSAR_PIDS" ]; then
        echo "✓ Pulsar launched — giving renderer 2s to spawn before prioritizing..."
        sleep 2
        PULSAR_PIDS=$(pgrep -f pulsar)
      else
        echo "⚠ Pulsar didn't appear within 10s — skipping priority set"
      fi
    else
      echo "⚠ No user session detected (no kwin/plasma) — skipping Pulsar auto-launch"
    fi
  fi

  if [ ! -z "$PULSAR_PIDS" ]; then
    if [ "$mode" != "standard" ]; then
      # Extreme/cool: low but NOT idle — keeps editor usable while livecoding
      for PID in $PULSAR_PIDS; do
        renice -n 10 -p $PID >/dev/null 2>&1
        ionice -c 2 -n 6 -p $PID >/dev/null 2>&1
      done
      echo "✓ Set Pulsar processes to low priority (nice 10, best-effort I/O 6)"
    else
      # Standard mode: slightly lower
      for PID in $PULSAR_PIDS; do
        renice -n 5 -p $PID >/dev/null 2>&1
        ionice -c 2 -n 5 -p $PID >/dev/null 2>&1
      done
      echo "✓ Set Pulsar processes to slightly lower priority (nice 5)"
    fi
  else
    echo "ℹ️ Pulsar processes not found - skipping"
  fi
  
  # Adjust desktop environment components
  # KDE Window Manager (X11 or Wayland)
  KWIN_PID=$(pgrep -x kwin_x11 || pgrep -x kwin_wayland)
  if [ ! -z "$KWIN_PID" ]; then
    if [ "$mode" != "standard" ]; then
      renice -n 10 -p $KWIN_PID >/dev/null 2>&1
      ionice -c 2 -n 6 -p $KWIN_PID >/dev/null 2>&1
      echo "✓ Set KWin (PID $KWIN_PID) to nice 10 (low but not starved)"
    else
      renice -n 5 -p $KWIN_PID >/dev/null 2>&1
      echo "✓ Set KWin (PID $KWIN_PID) to nice 5"
    fi
  fi

  # Plasma Shell
  PLASMA_PID=$(pgrep -x plasmashell)
  if [ ! -z "$PLASMA_PID" ]; then
    if [ "$mode" != "standard" ]; then
      renice -n 15 -p $PLASMA_PID >/dev/null 2>&1
      ionice -c 2 -n 7 -p $PLASMA_PID >/dev/null 2>&1
      echo "✓ Set Plasma Shell (PID $PLASMA_PID) to nice 15"
    else
      renice -n 5 -p $PLASMA_PID >/dev/null 2>&1
      echo "✓ Set Plasma Shell (PID $PLASMA_PID) to nice 5"
    fi
  fi

  # Display server — keep at normal priority always
  # Demoting Xorg/Xwayland just makes every window repaint laggy
  DISPLAY_PID=$(pgrep -x Xorg || pgrep -x Xwayland)
  if [ ! -z "$DISPLAY_PID" ]; then
    renice -n 0 -p $DISPLAY_PID >/dev/null 2>&1
    echo "✓ Keeping display server (PID $DISPLAY_PID) at normal priority"
  fi
  
  echo "Priority setup complete!"
}

# Function to stop performance mode and revert settings
reset_system() {
  check_root "--stop"
  
  echo "========================================="
  echo "RESTORING NORMAL SYSTEM SETTINGS"
  echo "========================================="
  
  # Restore CPU governor
  if [ -f "$SAVED_CPU_GOVERNOR" ]; then
    echo "Restoring CPU governor to previous mode..."
    previous_governor=$(cat $SAVED_CPU_GOVERNOR)
    echo $previous_governor | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
    echo "✓ CPU governor restored to $previous_governor"
    rm $SAVED_CPU_GOVERNOR
  else
    echo "Restoring CPU governor to default mode..."
    echo ondemand | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
    echo "✓ CPU governor restored to ondemand"
  fi
  
  # Restore swappiness
  echo "Restoring swap settings..."
  echo 60 > /proc/sys/vm/swappiness
  echo "✓ Swappiness restored to default (60)"
  
  # Restore VM settings
  echo "Restoring VM settings..."
  echo 0 > /proc/sys/vm/dirty_bytes
  echo 0 > /proc/sys/vm/dirty_background_bytes
  echo "✓ VM buffer parameters restored"
  
  # Restore Intel pstate if needed
  if [ -f "/sys/devices/system/cpu/intel_pstate/no_turbo" ]; then
    echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
    echo "✓ CPU Turbo re-enabled"
  fi
  
  if [ -d "/sys/devices/system/cpu/intel_pstate" ]; then
    echo 0 > /sys/devices/system/cpu/intel_pstate/min_perf_pct 2>/dev/null
    # Restore the peak-clock cap (--cool lowers it; --extreme leaves it at 100)
    if [ -f "$SAVED_MAX_PCT" ]; then
      cat "$SAVED_MAX_PCT" > /sys/devices/system/cpu/intel_pstate/max_perf_pct 2>/dev/null
      rm -f "$SAVED_MAX_PCT"
    else
      echo 100 > /sys/devices/system/cpu/intel_pstate/max_perf_pct 2>/dev/null
    fi
    echo "✓ Intel CPU perf caps reset"
  fi

  # Restore EPP (energy/perf hint) if --cool changed it
  if [ -f "$SAVED_EPP" ] && [ -f /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference ]; then
    cat "$SAVED_EPP" | tee /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference > /dev/null 2>&1
    rm -f "$SAVED_EPP"
    echo "✓ EPP restored"
  fi
  
  # Restore NMI watchdog
  echo 1 > /proc/sys/kernel/nmi_watchdog
  echo "✓ NMI watchdog restored"
  
  # Restore kernel logging level
  echo 7 4 1 7 > /proc/sys/kernel/printk
  echo "✓ Kernel logging level restored"
  
  # Restart system services
  echo "Restarting system services..."
  systemctl unmask packagekit.service 2>/dev/null
  systemctl start packagekit.service 2>/dev/null
  rm -f /run/systemd/journald.conf.d/perf.conf 2>/dev/null
  systemctl reload systemd-journald.service 2>/dev/null
  echo "✓ System services restarted"
  
  # Restore nice values for processes - you can keep your apps running
  echo "Restoring process priorities..."
  
  # Reset SuperCollider priorities if running
  SC_SERVER=$(pgrep scsynth)
  SC_LANG=$(pgrep sclang)
  
  if [ ! -z "$SC_SERVER" ]; then
    chrt -o -p 0 $SC_SERVER
    echo 0 > /proc/$SC_SERVER/oom_score_adj 2>/dev/null
    echo "✓ Reset scsynth (PID $SC_SERVER) to normal priority"
  fi
  
  if [ ! -z "$SC_LANG" ]; then
    chrt -o -p 0 $SC_LANG
    echo 0 > /proc/$SC_LANG/oom_score_adj 2>/dev/null
    echo "✓ Reset sclang (PID $SC_LANG) to normal priority"
  fi
  
  # Find Ardour process if running
  ARDOUR=$(pgrep -f "ardour-8|/ardour|ardour8")
  if [ ! -z "$ARDOUR" ]; then
    chrt -o -p 0 $ARDOUR
    ionice -c 2 -n 4 -p $ARDOUR
    echo 0 > /proc/$ARDOUR/oom_score_adj 2>/dev/null
    echo "✓ Reset Ardour (PID $ARDOUR) to normal priority"
  fi
  
  # Reset nice values for UI processes
  KWIN_PID=$(pgrep -x kwin_x11 || pgrep -x kwin_wayland)
  if [ ! -z "$KWIN_PID" ]; then
    renice -n 0 -p $KWIN_PID
    ionice -c 2 -n 4 -p $KWIN_PID
    echo "✓ Reset KWin (PID $KWIN_PID) to normal priority"
  fi

  PLASMASHELL_PID=$(pgrep -x plasmashell)
  if [ ! -z "$PLASMASHELL_PID" ]; then
    renice -n 0 -p $PLASMASHELL_PID
    ionice -c 2 -n 4 -p $PLASMASHELL_PID
    echo "✓ Reset Plasma Shell (PID $PLASMASHELL_PID) to normal priority"
  fi

  DISPLAY_PID=$(pgrep -x Xorg || pgrep -x Xwayland)
  if [ ! -z "$DISPLAY_PID" ]; then
    renice -n 0 -p $DISPLAY_PID
    echo "✓ Reset display server (PID $DISPLAY_PID) to normal priority"
  fi
  
  # Reset Pulsar processes if running
  PULSAR_PIDS=$(pgrep -f pulsar)
  if [ ! -z "$PULSAR_PIDS" ]; then
    for PID in $PULSAR_PIDS; do
      renice -n 0 -p $PID
      ionice -c 2 -n 4 -p $PID
    done
    echo "✓ Reset Pulsar processes to normal priority"
  fi
  
  # Restart services
  echo "Restarting services..."
  USER=$(logname || whoami)
  systemctl --user -M $USER@ start kde-baloo.service 2>/dev/null
  systemctl --user -M $USER@ start plasma-baloorunner.service 2>/dev/null
  systemctl --user -M $USER@ start app-geoclue-demo-agent@autostart.service 2>/dev/null
  systemctl --user -M $USER@ start app-firewall-applet@autostart.service 2>/dev/null
  systemctl --user -M $USER@ start kaccess.service 2>/dev/null
  systemctl --user -M $USER@ start plasma-ksystemstats.service 2>/dev/null
  systemctl --user -M $USER@ start plasma-dolphin.service 2>/dev/null
  echo "✓ Services restarted"
  
  echo "System restored to normal operation. You can continue using your apps."
}

# Main script execution
USER=$(logname || whoami)
case "$1" in
  --optimize)
    optimize_standard
    ;;
  --extreme)
    optimize_extreme
    ;;
  --cool)
    optimize_cool
    ;;
  --stop)
    reset_system
    ;;
  --check)
    check_system_load
    ;;
  --diagnose)
    run_diagnostics
    ;;
  --help|*)
    show_help
    ;;
esac