import re
from .channel import Channel
from .bioflowinsighterror import BioFlowInsightError
from . import constant


class Emitted(Channel):

    def __init__(self, name, origin, emitted_by):
        Channel.__init__(self, name=name, origin=origin)

        self.emitted_by = emitted_by
        emitted_by.add_to_emits(self)

        
        self.source.append(emitted_by)
        self.emits = None #->this is the channel it's emits -> in the case of a subworkflow

    def get_emitted_by(self):
        return self.emitted_by
    
    def get_emits(self):
        return self.emits

    def get_type(self):
        return "Emitted"

    def set_emits_decimal(self, decimal):
        thing_which_emits = self.emitted_by.get_first_element_called()
        self.emits = thing_which_emits.get_emit()[decimal]

    def set_emits_name(self, name):
        thing_which_emits = self.emitted_by.get_first_element_called()
        emitted = thing_which_emits.get_emit()
        
        for o in emitted:
            code = o.get_code()
            if(code[:len("emit:")]=="emit:"):
                code =code[len("emit:"):].strip()
            if(name==code):
                self.emits = o
            else:
                for match in re.finditer(constant.WORD_EQUALS, code):
                    if(name==match.group(1)):
                        self.emits = o
        
        if(self.emits==None):
            raise Exception(f"No emitted matched with '{name}' (in file '{self.get_file_address()}'). Should match with emittes from '{self.emitted_by.get_first_element_called().get_name()}' (in file '{self.emitted_by.get_file_address()}'")

    def set_emits(self, input):
        thing_which_emits = self.emitted_by.get_first_element_called()
        if(thing_which_emits.get_type()=="Process"):
            #TODO -> i don't konw what to do with this
            #self.emits = thing_which_emits
            None
            
        else:
            if(input!=""):
                try:
                    input = int(input)
                    self.set_emits_decimal(decimal=input)
                except:
                    self.set_emits_name(name=input)
            else:
                if(thing_which_emits.get_type()=='Subworkflow'):
                    if(len(thing_which_emits.emit)!=1):
                        raise BioFlowInsightError(f"One channel was expected in the emit '{self.get_code()}'. Even though multiple emits are defined for the workflow '{self.emitted_by.get_name()}'", num=6, origin=self)
                    self.emits = thing_which_emits.emit[0]
                else:
                    raise Exception("This shoudn't happen!")

    def get_structure(self, dico, B):
        emits = self.get_emitted_by()
        if(emits.get_type()=="Call"):
            first_element_called = emits.get_first_element_called()
            if(first_element_called.get_type()=="Process"):
                dico["edges"].append({'A':str(first_element_called), 'B':str(B), "label":self.get_code()})
            elif(first_element_called.get_type()=="Subworkflow"):
                if(self.emits==None):
                    raise Exception("Just a check")
                else:

                    dico["edges"].append({'A':str(self.emits), 'B':str(B), "label":self.get_name()})
        else:
            raise Exception("This shouldn't happen")