import sys

from PyQt5.QtGui import QPalette
from ui.test_test import Test_Test


class Test_Resistance(Test_Test):
    def __init__(self, components=None, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=True):
        super().__init__(components=components, recipe=recipe, step=step, pieces=pieces, run_once=run_once, reset_on_start=reset_on_start, enable_override=enable_override)
        self.ok_counter_limit = 3

    def start(self, recipe=None, step=None, pieces=None):
        # TESTING
        if "--test-resistance" in sys.argv or "--test" in sys.argv:
            self.simulate = True
        else:
            self.simulate = False
        # /TESTING
        expected = step.spec.get("expected", "-")
        if expected == float("+inf"):
            step.spec["expected"] = 1e9
        show = super().start(recipe=recipe, step=step, pieces=pieces)
        if show is False:
            return show
        # setup test loop
        self.components["multicomp"].set_resistance_scale(self.step.spec.get("scale", 500))
        self.get_connection = self.components["multicomp"].out.connect(self.get)
        self.components["multicomp"].resume()
        expected = self.step.spec.get("expected", "-")
        if self.step.spec.get("autotest", False) is not True:
            if expected == 1e9:
                self.ok_counter_limit = 1
                if self.parent_assembly_widget is not None:
                    self.parent_assembly_widget().set_text("SCOLLEGARE IL CONNETTORE")
            else:
                self.ok_counter_limit = 3
                if self.parent_assembly_widget is not None:
                    self.parent_assembly_widget().set_text("VERIFICARE CONTROLLO RESISTENZA")
        else:
            if expected == 1e9:
                self.ok_counter_limit = 1
                if self.parent_assembly_widget is not None:
                    self.parent_assembly_widget().set_text("AUTOTEST: SCOLLEGARE IL CONNETTORE DI PROVA")
            else:
                self.ok_counter_limit = 3
                if self.parent_assembly_widget is not None:
                    self.parent_assembly_widget().set_text("AUTOTEST: VERIFICARE CONTROLLO RESISTENZA DI PROVA")
        self.expected_l.setText(f"{expected}")
        tolerance_pos = self.step.spec.get("tolerance_pos", "-")
        tolerance_neg = self.step.spec.get("tolerance_neg", "-")
        self.tolerance_pos_l.setText(f"{tolerance_pos}")
        self.tolerance_neg_l.setText(f"-{tolerance_neg}")
        if all([
            isinstance(expected, (int, float)),
            isinstance(tolerance_pos, (int, float)),
            isinstance(tolerance_neg, (int, float)),
        ]):
            min_tolerance = round(expected * (1 - tolerance_neg / 100), 2)
            max_tolerance = round(expected * (1 + tolerance_pos / 100), 2)
        else:
            min_tolerance = "-"
            max_tolerance = "-"
        self.tolerance_min_l.setText(f"{min_tolerance}")
        self.tolerance_max_l.setText(f"{max_tolerance}")
        bg = self.status_palettes[None].color(QPalette.Background)
        color = f"rgb({bg.red()}, {bg.green()}, {bg.blue()})"
        self.resistance_l.setStyleSheet(f"background-color: {color};\nborder: 1px solid black;\n")
        return show

    def stop(self):
        # disable test loop
        self.components["multicomp"].pause()
        self.disconnect(self.get_connection)
        super().stop()

    # def reset(self):
    #     super().reset()

    def get(self, data=None, override=False):
        if self.done:  # avoid proccessing if completed
            return
        if data is None or data[-1] is None:
            super().get(None, override=override)
            return
        data = data[-1]
        # TESTING
        if self.simulate:
            data["multicomp"] = {
                "function": "\"RES\"",
                "scale": self.step.spec.get("scale", 500),
                "measure": self.step.spec.get("expected", 0),
            }
        # /TESTING
        result = data["multicomp"].get("measure", None)
        expected = self.step.spec.get("expected", "-")
        tolerance_pos = self.step.spec.get("tolerance_pos", "-")
        tolerance_neg = self.step.spec.get("tolerance_neg", "-")
        if all([
            isinstance(result, (int, float)),
            isinstance(expected, (int, float)),
            isinstance(tolerance_pos, (int, float)),
            isinstance(tolerance_neg, (int, float)),
        ]):
            if expected * (1 - tolerance_neg / 100) <= result <= expected * (1 + tolerance_pos / 100):
                ok = True
            else:
                ok = None
        else:
            ok = None
        super().get([{
            "time": data.get("time", None),
            "results": {
                "ok": ok,
                "result": result,
                "data": data["multicomp"],
            },
        }], override=override, fail=ok is False)

    def visualize(self, data=None):
        if data is None:
            data = {}
        d = data.get("results", {}).get("data", {})
        for k, l in {
            # "scale": self.scale_l,
            "measure": self.resistance_l,
        }.items():
            v = d.get(k, "-")
            if type(v) is float:
                v = round(v, 2)
            l.setText(str(v))
        ok = data.get("results", {}).get("ok", None)
        r = d.get("measure", None)
        i = ok
        p = ok
        if i is None and r != 1e9:
            i = "wait"
        if p is None:
            if r == 1e9:
                p = "warning"
            else:
                p = False
        bg = self.status_palettes[p].color(QPalette.Base)
        color = f"rgb({bg.red()}, {bg.green()}, {bg.blue()})"
        self.resistance_l.setStyleSheet(f"background-color: {color};\nborder: 1px solid black;\n")
        super().visualize(data, img=self.status_imgs_full[i])

    def save_last(self):
        if self.last is None:
            return
