# -*- coding: utf-8 -*-


class Node:
    """
    A class to represent the nodes in SCRDR tree
    """

    def __init__(
        self,
        condition,
        conclusion,
        father=None,
        exceptChild=None,
        elseChild=None,
        cornerstoneCases=[],
        depth=0,
    ):
        self.condition = condition
        self.conclusion = conclusion
        self.exceptChild = exceptChild
        self.elseChild = elseChild
        self.cornerstoneCases = cornerstoneCases
        self.father = father
        self.depth = depth

    def satisfied(self, object):
        return eval(self.condition)

    def executeConclusion(self, object):
        exec(self.conclusion)

    def appendCornerstoneCase(self, object):
        self.cornerstoneCases.append(object)

    def check(self, object):
        if self.satisfied(object):
            self.executeConclusion(object)
            if self.exceptChild != None:
                self.exceptChild.check(object)
        else:
            if self.elseChild != None:
                self.elseChild.check(object)

    def checkDepth(self, object, length):
        if self.depth <= length:
            if self.satisfied(object):
                self.executeConclusion(object)
                if self.exceptChild != None:
                    self.exceptChild.checkDepth(object, length)
            else:
                if self.elseChild != None:
                    self.elseChild.checkDepth(object, length)

    def findRealFather(self):
        node = self
        fatherNode = node.father
        while True and fatherNode != None:
            if fatherNode.exceptChild == node:
                break
            node = fatherNode
            fatherNode = node.father
        return fatherNode

    def addElseChild(self, node):
        fatherNode = self.findRealFather()
        for object in fatherNode.cornerstoneCases:
            if node.satisfied(object):
                print("The new rule fires the cornerstone cases of its father node!!!")
                self.findRealFather().cornerstoneCases.remove(object)
        self.elseChild = node
        return True

    def addExceptChild(self, node):
        for object in self.cornerstoneCases:
            if node.satisfied(object):
                print("The new rule fires the cornerstone cases of its father node!!!")
                self.cornerstoneCases.remove(object)
        self.exceptChild = node
        return True

    def writeToFileWithSeenCases(self, out, depth):
        space = tabStr(depth)
        out.write(space + self.condition + " : " + self.conclusion + "\n")
        for case in self.cornerstoneCases:
            out.write(" " + space + "cc: " + case.toStr() + "\n")
        if self.exceptChild != None:
            self.exceptChild.writeToFile(out, depth + 1)
        if self.elseChild != None:
            self.elseChild.writeToFile(out, depth)

    def writeToFile(self, out, depth):
        space = tabStr(depth)
        out.write(space + self.condition + " : " + self.conclusion + "\n")
        if self.exceptChild != None:
            self.exceptChild.writeToFile(out, depth + 1)
        if self.elseChild != None:
            self.elseChild.writeToFile(out, depth)


def tabStr(length):
    return "".join(["\t"] * length)
