from ...abc import Expression

from ..value.valueexpr import VALUE


class WHEN(Expression):
    """
    Checks "if" condition passes - it is an `if` on steroids ;-)

    !WHEN
    - is:
            !EQ
            - !ITEM EVENT eggs
            - 2
    then: eggs

    - is:
            !LT
            - 9
            - !ITEM EVENT potatoes
            - 11
    then: potatoes

    - else:
            Nah

    """

    Attributes = False  # Filled during initialize() since attributes are dynamic

    Category = "Statements"

    def __init__(self, app, *, sequence):
        super().__init__(app)
        self.Items = sequence
        self.ItemsNormalized = []
        self.Attributes = {}
        self.OutletType = None  # Will be determined in `initialize()`
        self.Else = VALUE(self.App, value=None)

    def set(self, key, value):
        setattr(self, key, value)

        if "Test" in key:
            item_normalized = self.ItemsNormalized[int(key[4:])]
            self.ItemsNormalized[int(key[4:])] = (value, item_normalized[1])

        if "Then" in key:
            item_normalized = self.ItemsNormalized[int(key[4:])]
            self.ItemsNormalized[int(key[4:])] = (item_normalized[0], value)

    def initialize(self):
        item_counter = 0
        for n, i in enumerate(self.Items):
            # `test/then` branch
            if "test" in i and "then" in i:
                assert len(i) == 2

                vtest = i["test"]
                if not isinstance(vtest, Expression):
                    vtest = VALUE(self.App, value=vtest)

                attr_name = "Test{}".format(item_counter)
                setattr(self, attr_name, vtest)
                self.Attributes[attr_name] = [bool.__name__]

                vthen = i["then"]
                if not isinstance(vthen, Expression):
                    vthen = VALUE(self.App, value=vthen)

                attr_name = "Then{}".format(item_counter)
                setattr(self, attr_name, vthen)
                if self.OutletType is None:
                    self.OutletType = vthen.get_outlet_type()
                self.Attributes[attr_name] = self.OutletType

                self.ItemsNormalized.append((vtest, vthen))
                item_counter += 1

            # `else` branch
            elif "else" in i:
                assert len(i) == 1
                # TODO: Fix double-initialization when doing INCLUDE
                # assert('Else' not in self.Attributes)

                v = i["else"]
                if not isinstance(v, Expression):
                    v = VALUE(self.App, value=v)

                attr_name = "Else"
                setattr(self, attr_name, v)
                if self.OutletType is None:
                    self.OutletType = v.get_outlet_type()

                self.Attributes[attr_name] = self.OutletType

            else:
                raise RuntimeError("Unexpected items in '!WHEN': {}".format(i.keys()))

    def __call__(self, context, event, *args, **kwargs):
        for test, then in self.ItemsNormalized:
            res = test(context, event, *args, **kwargs)
            if res:
                return then(context, event, *args, **kwargs)

        return self.Else(context, event, *args, **kwargs)

    def get_outlet_type(self):
        return self.OutletType
