#!/usr/bin/env python3
# -------------------------------------------------------------------- #
# CPUnotify alerts operational CPU spikes above 100%
# -------------------------------------------------------------------- #
# License: GPL v2 or later
# Version: 1.0.3
# -------------------------------------------------------------------- #

import os
import time
import psutil
import subprocess

TRAY_SCRIPT = "/usr/share/cpunotify/CPUnotify"
TMP_CPU_FILE = "/tmp/cpunotify"
TMP_USAGE_FILE = "/tmp/cpu_usage"
ALERT_SOUND = "/usr/share/sounds/freedesktop/stereo/dialog-error.oga"


def tray_running():
    """Return True if CPUnotify tray process is already running."""
    try:
        result = subprocess.run(
            ["pgrep", "-f", TRAY_SCRIPT],
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL,
            text=True,
        )
        return bool(result.stdout.strip())
    except Exception:
        return False


def start_tray():
    """Start tray icon if not already running."""
    if not tray_running():
        subprocess.Popen(["python3", TRAY_SCRIPT], stderr=subprocess.DEVNULL)


def write_tmp_files(cpu_usage):
    """Write current CPU usage to /tmp files."""
    with open(TMP_CPU_FILE, "w") as f:
        f.write(str(int(cpu_usage)))

    if cpu_usage > 100:
        msg = f"CPU Usage is {int(cpu_usage)}% High"
    else:
        msg = f"CPU Usage is {int(cpu_usage)}% Normal"

    with open(TMP_USAGE_FILE, "w") as f:
        f.write(msg)


def play_alert():
    """Play alert sound if usage exceeds 100%."""
    subprocess.Popen(["pw-play", ALERT_SOUND], stderr=subprocess.DEVNULL)


def monitor():
    """Main monitoring loop."""
    start_tray()

    while True:
        # Measure CPU usage across all cores (percentage)
        cpu_usage = psutil.cpu_percent(interval=1)
        write_tmp_files(cpu_usage)

        if cpu_usage > 100:
            play_alert()
            # Check again in 1 second
            time.sleep(1)
        else:
            # Normal usage; wait 40 seconds before next check
            time.sleep(40)


if __name__ == "__main__":
    monitor()

