from instruction import *
from log import gen_log
import copy


class PiecewiseContext(object):
    def __init__(self):
        self.variable_map = {}
        self.instructs = []
        # {label num:instructions index}
        self.labels = {}
        self.brs_index = []
        self.labels_index = []

    def interpret(self, commands):
        # Scan all the commands to get the structure
        for i, command in enumerate(commands):
            instruct = InstructionFactory.parse(command)
            self.instructs.append(command)
            if instruct:
                # instruct.refresh_variable(self.variable_map)
                if isinstance(instruct, BRInstruction):
                    self.brs_index.append(i)
                elif isinstance(instruct, LABELInstruction):
                    self.labels[instruct.num] = i
                    self.labels_index.append(i)
            else:
                gen_log.warning("cannot parse command: " + command)

        # Load all commands before the first branch
        for i in range(self.brs_index[0] + 1):
            instruct = InstructionFactory.parse(self.instructs[i])
            if instruct:
                instruct.refresh_variable(self.variable_map)

        # for i in self.brs_index:
        #     temp_map = copy.deepcopy(self.variable_map)
        #     print(temp_map)
        #     br = InstructionFactory.parse(self.instructs[i])
        #     if not br.isdirect():
        #         first_label = br.first_label
        #         second_label = br.second_label
        #         first_result = self.__scan_instructs_left(first_label, temp_map)
        #         second_result = self.__scan_instructs_left(second_label, temp_map)
        #         print(first_result + "," + br.cmp)
        #         if second_result:
        #             print(second_result + "," + self.reverse_cmp_condition(br.cmp))
        #     print(temp_map)
        temp_map = copy.deepcopy(self.variable_map)
        # for i in self.brs_index:
        self.__scan_util_br(self.brs_index[0], temp_map)

    @staticmethod
    def reverse_cmp_condition(cmp):
        result = ""
        if ">=" in cmp:
            result = cmp.replace(">=", "<")
        elif "=<" in cmp:
            result = cmp.replace("<=", ">")
        elif ">" in cmp:
            result = cmp.replace(">", "<=")
        elif "<" in cmp:
            result = cmp.replace("<", ">=")
        return result

    def __scan_util_br(self, br_index, vmap):
        temp_map = copy.deepcopy(vmap)
        br = InstructionFactory.parse(self.instructs[br_index])
        if not br.isdirect():
            first_label = br.first_label
            second_label = br.second_label
            first_result = self.__scan_instructs_left(first_label, temp_map)
            second_result = self.__scan_instructs_left(second_label, temp_map)
            if first_result:
                print(first_result + "," + br.cmp)
            if second_result:
                print(second_result + "," + self.reverse_cmp_condition(br.cmp))

    def __scan_instructs_left(self, label, temp_map):
        t = copy.deepcopy(temp_map)
        for i in range(self.labels[label], self.__get_next_label_index(label)):
            instruct = InstructionFactory.parse(self.instructs[i])
            if instruct:
                instruct.refresh_variable(temp_map)
                if isinstance(instruct, BRInstruction):
                    if instruct.isdirect():
                        for j in range(self.labels[instruct.target], len(self.instructs)):
                            instruct = InstructionFactory.parse(self.instructs[j])
                            if instruct:
                                instruct.refresh_variable(temp_map)
                            if isinstance(instruct, ReturnInstruction):
                                print(temp_map)
                                return instruct.result
                    else:
                        self.__scan_util_br(i, t)

    def __get_next_label_index(self, label_num):
        index = self.labels_index.index(self.labels[label_num])
        return self.labels_index[index + 1]

@@ -1263,50 +1263,8 @@
 %0A   
-     # for i in self.brs_index:%0D%0A        #
     
@@ -1313,706 +1313,8 @@
 p)%0D%0A
-        #     print(temp_map)%0D%0A        #     br = InstructionFactory.parse(self.instructs%5Bi%5D)%0D%0A        #     if not br.isdirect():%0D%0A        #         first_label = br.first_label%0D%0A        #         second_label = br.second_label%0D%0A        #         first_result = self.__scan_instructs_left(first_label, temp_map)%0D%0A        #         second_result = self.__scan_instructs_left(second_label, temp_map)%0D%0A        #         print(first_result + %22,%22 + br.cmp)%0D%0A        #         if second_result:%0D%0A        #             print(second_result + %22,%22 + self.reverse_cmp_condition(br.cmp))%0D%0A        #     print(temp_map)%0D%0A        temp_map = copy.deepcopy(self.variable_map)%0D%0A        # for i in self.brs_index:%0D%0A
     
@@ -1806,48 +1806,8 @@
 ):%0D%0A
-        temp_map = copy.deepcopy(vmap)%0D%0A
     
@@ -1863,24 +1863,59 @@
 br_index%5D)%0D%0A
+        br.refresh_variable(vmap)%0D%0A
         if n
@@ -2011,32 +2011,76 @@
 r.second_label%0D%0A
+            temp_map = copy.deepcopy(vmap)%0D%0A
             firs
@@ -2133,32 +2133,76 @@
 bel, temp_map)%0D%0A
+            temp_map = copy.deepcopy(vmap)%0D%0A
             seco
@@ -2389,24 +2389,26 @@
             
+ #
  print(secon
@@ -2460,16 +2460,119 @@
 r.cmp))%0D
+%0A                # TODO Adjust to support more than two branches%0D%0A                print(second_result)%0D
 %0A%0D%0A    d
@@ -2625,45 +2625,8 @@
 ):%0D%0A
-        t = copy.deepcopy(temp_map)%0D%0A
     
@@ -3315,57 +3315,8 @@
 ):%0D%0A
-                                print(temp_map)%0D%0A
     
@@ -3386,32 +3386,32 @@
          else:%0D%0A
-
                 
@@ -3442,16 +3442,23 @@
 _br(i, t
+emp_map
 )%0D%0A%0D%0A   

Fix bugs with dealing with BR instructions.