import re
import subprocess
from abc import ABC

from fw_fanctrl.hardwareController.HardwareController import HardwareController


class EctoolHardwareController(HardwareController, ABC):
    noBatterySensorMode = False
    nonBatterySensors = None

    def __init__(self, no_battery_sensor_mode=False):
        if no_battery_sensor_mode:
            self.noBatterySensorMode = True
            self.populate_non_battery_sensors()

    def populate_non_battery_sensors(self):
        self.nonBatterySensors = []
        raw_out = subprocess.run(
            "ectool tempsinfo all",
            stdout=subprocess.PIPE,
            shell=True,
            text=True,
        ).stdout
        battery_sensors_raw = re.findall(r"\d+ Battery", raw_out, re.MULTILINE)
        battery_sensors = [x.split(" ")[0] for x in battery_sensors_raw]
        for x in re.findall(r"^\d+", raw_out, re.MULTILINE):
            if x not in battery_sensors:
                self.nonBatterySensors.append(x)

    def get_temperature(self):
        if self.noBatterySensorMode:
            raw_out = "".join(
                [
                    subprocess.run(
                        "ectool temps " + x,
                        stdout=subprocess.PIPE,
                        shell=True,
                        text=True,
                    ).stdout
                    for x in self.nonBatterySensors
                ]
            )
        else:
            raw_out = subprocess.run(
                "ectool temps all",
                stdout=subprocess.PIPE,
                shell=True,
                text=True,
            ).stdout
        raw_temps = re.findall(r"\(= (\d+) C\)", raw_out)
        temps = sorted([x for x in [int(x) for x in raw_temps] if x > 0], reverse=True)
        # safety fallback to avoid damaging hardware
        if len(temps) == 0:
            return 50
        return float(round(temps[0], 2))

    def set_speed(self, speed):
        subprocess.run(f"ectool fanduty {speed}", stdout=subprocess.PIPE, shell=True)

    def is_on_ac(self):
        raw_out = subprocess.run(
            "ectool battery",
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL,
            shell=True,
            text=True,
        ).stdout
        return len(re.findall(r"Flags.*(AC_PRESENT)", raw_out)) > 0

    def pause(self):
        subprocess.run("ectool autofanctrl", stdout=subprocess.PIPE, shell=True)

    def resume(self):
        # Empty for ectool, as setting an arbitrary speed disables the automatic fan control
        pass
