#!/usr/bin/env python

import os
import os.path
import subprocess
import sys

os.chdir(os.path.expanduser("~/.config/hypr"))
bars = "_▂▃▄▅▆▇█"
batteries = "󰂎󰁺󰁻󰁼󰁽󰁾󰁿󰂀󰂁󰂁󰁹"
batteries_charging = "󰢟󰢜󰂆󰂇󰂈󰢝󰂉󰢞󰂊󰂋󰂅"


def to_bar(x):
    return bars[round((len(bars) - 1) * x / 100)]


def monitor_stats():
    """
    Monitors CPU and MEM usage and prints info in file.
    """

    try:
        import psutil
    except ModuleNotFoundError:
        print("Stats requires psutil (run `pip install psutil`)", file=sys.stderr)
        sys.exit(1)

    cpu_values = [0] * 10
    mem_values = [0] * 10
    temp_values = [0] * 10

    min_temp = 45
    max_temp = 95

    while True:
        cpu_percent = psutil.cpu_percent(interval=2)
        mem_percent = psutil.virtual_memory().percent
        battery = psutil.sensors_battery()
        all_temps = psutil.sensors_temperatures(fahrenheit=False)

        temps = all_temps.get("k10temp", None)
        if temps is None:
            temps = all_temps.get("coretemp")

        temp = max([x.current for x in temps if x.label != "Tctl"])

        temp_percent = 100 * min(max([temp - min_temp, 0]) / (max_temp - min_temp), 1)

        for i in range(len(cpu_values) - 1):
            cpu_values[i] = cpu_values[i + 1]
            mem_values[i] = mem_values[i + 1]
            temp_values[i] = temp_values[i + 1]

        cpu_values[-1] = cpu_percent
        mem_values[-1] = mem_percent
        temp_values[-1] = temp_percent

        # Notify when memory greater than 75%
        if mem_percent >= 75 and not any(map(lambda x: x > 75, mem_values[:-1])):
            subprocess.run(
                [
                    "notify-send",
                    "-u",
                    "critical",
                    "High memory usage",
                    "% 5.1f" % mem_percent + "% of RAM used",
                ]
            )

        if battery is None:
            battery_json = '{"text": "", "class": "hidden"}'
        else:
            battery_index = round(battery.percent / 10)
            battery_icon = (
                batteries_charging[battery_index]
                if battery.power_plugged
                else batteries[battery_index]
            )

            if battery.power_plugged:
                battery_class = "charging"
            elif battery.percent < 30.0:
                battery_class = "low"
            elif battery.percent < 15.0:
                battery_class = "critical"
            else:
                battery_class = None

            battery_text = (
                "% 4.0f" % battery.percent if battery.percent <= 99.95 else "  100"
            )
            battery_json = f', "class": "{battery_class}"' if battery_class else ""
            battery_json = (
                '{"text": "'
                + battery_icon
                + " "
                + battery_text
                + '%"'
                + battery_json
                + "}"
            )

        cpu_percent_text = "% 5.1f" % cpu_percent if cpu_percent <= 99.95 else "  100"
        mem_percent_text = "% 5.1f" % mem_percent if mem_percent <= 99.95 else "  100"

        with open(".stat.txt", "w") as f:
            f.write(
                "  "
                + "".join([to_bar(x) for x in cpu_values])
                + " "
                + cpu_percent_text
                + "%\n"
                + "  "
                + "".join([to_bar(x) for x in mem_values])
                + " "
                + mem_percent_text
                + "%\n"
                + "  "
                + "".join([to_bar(x) for x in temp_values])
                + " "
                + "% 5.1f" % temp
                + "°\n"
                + battery_json
            )


def start_hyprlock():
    proc = subprocess.run(["pidof", "hyprlock"])
    if proc.returncode != 0:
        # We need to start this in the background so that the screen turns off afterwards
        subprocess.Popen(["hyprlock"], start_new_session=True)


def lock_session():
    if os.environ.get("HYPR_DISABLE_LOCK", None) is None:
        subprocess.run(["loginctl", "lock-session"])


def main():
    monitor_stats()


if __name__ == "__main__":
    main()
