# Path: logparser/MoLFI/main/org/core/chromosome/chromosome.py
# class Chromosome:
#     """ A chromosome in this class is a dictionary
#         key: int
#         value: List[Templates]
#     """
# 
#     def __init__(self, p_templates: dict()):
#         """ The constructor with an attribute of type List of Template
#         :param p_templates: a dictionary of Template
#         """
#         self.templates = p_templates
#         self.coverage = 0
# 
#     def add_template(self, template: Template):
#         """ Adds a template to the chromosome
#         
#         :param template: an object of type Template
#         :return: the template will be added to the corresponding cluster
#         with key = len(template)
#         """
#         key = template.get_length()
#         if key in self.templates.keys():
#             self.templates[key].append(template)
#         else:
#             self.templates[key] = []
#             self.templates[key].append(template)
# 
#     def delete_template(self, template: Template):
#         """ Deletes the template from the given cluster id      
#         :param 
#             index: cluster id
#         :return  
#             the cluster without the template
#         :raises 
#             IndexError: An error occurs if a negative cluster id is provided
#             or if the cluster id doesn't exist
#         """
#         key = template.get_length()
#         if key not in self.templates:
#             raise IndexError("No cluster with the giving id!")
# 
#         self.templates[key].remove(template)
# 
#     def number_of_clusters(self):
#         """ Get the number of clusters inside the chromosome
#         :return: 
#             an integer: number of cluster 
#         """
#         return len(self.templates.keys())
# 
#     def cluster_size(self, cluster_id: int):
#         """ Get the number of templates inside a given cluster
#         :return: 
#             an integer: number of templates 
#         """
#         return len(self.templates[cluster_id])
# 
#     def all_templates(self):
#         """ Returns the total number of templates of a chromosome
#         """
#         number_templates = 0
#         for key in self.templates.keys():
#             number_templates = number_templates + self.cluster_size(key)
#         return number_templates
# 
#     def to_string(self):
#         """ Prints the content of a chromosome
#        :return: all templates as a string 
#         """
#         s = ""
#         for list_t in self.templates.values():
#             for t in list_t:
# 
#                 s = s + t.to_string() + "\n"
#         return s
# 
# Path: logparser/MoLFI/main/org/core/chromosome/template.py
# class Template:
#     """ An object representing the smallest element of a chromosome which is a template
#         Template is a list of strings
#     """
# 
#     def __init__(self, p_template: List[str]):
#         """ The constructor of the Class Template
#         initialize the object with a list of strings
#         and initialize the frequency and specificity with 0.0
#         and an empty list that will contain the line number matching the template
#         """
#         self.token = p_template
#         self.specificity = 0.0
#         self.matched_lines = []
#         self.changed = True
# 
#     def get_length(self):
#         """ Gets the number of strings in the list    
#         """
#         return len(self.token)
# 
#     def to_string(self):
#         """ Returns the template's token as one string
#         """
#         s = "[ "
#         for i in self.token:
#             s = s+i+' '
# 
#         s = s + ']'
#         return s
# 
#     def is_changed(self):
#         """ Returns the status of the template (changed or did not change)
#         """
#         return self.changed
# 
#     def set_changed(self, p_changed : bool):
#         """ Sets the status of a template to True if one of its tokens changes,
#         else the status is False (not changed)
#         """
#         self.changed = p_changed


import random
from ..chromosome.chromosome import Chromosome
from ..chromosome.template import Template

    
    :param chromosome: the chromosome with the templates
    :param messages: the original log messages
    :return: possibly corrected templates
    """
    for key in chromosome.templates.keys():
        for template in chromosome.templates[key]:
            for index in range(0, len(template.token)):
                token = template.token[index]
                words = set([])
                # gets all values at position index from the matched lines
                if token == "*" or token == "#spec#":
                    for message_index in template.matched_lines:
                        message = messages[key][message_index]
                        words.add(message.words[index])
                    # if all matched lines have the same word,
                    # the star in the template will be replaced with that word
                    if len(words) == 1:
                        template.token[index] = words.pop()


def is_all_star_template(template: Template):
    has_no_star = False
    for token in template.token:
        if not (token == "*" or token.startswith("[") or token == "#spec#"):
            has_no_star = True
            break
    return not has_no_star



# Path: logparser/MoLFI/main/org/core/chromosome/chromosome.py
# class Chromosome:
#     """ A chromosome in this class is a dictionary
#         key: int
#         value: List[Templates]
#     """
# 
#     def __init__(self, p_templates: dict()):
#         """ The constructor with an attribute of type List of Template
#         :param p_templates: a dictionary of Template
#         """
#         self.templates = p_templates
#         self.coverage = 0
# 
#     def add_template(self, template: Template):
#         """ Adds a template to the chromosome
#         
#         :param template: an object of type Template
#         :return: the template will be added to the corresponding cluster
#         with key = len(template)
#         """
#         key = template.get_length()
#         if key in self.templates.keys():
#             self.templates[key].append(template)
#         else:
#             self.templates[key] = []
#             self.templates[key].append(template)
# 
#     def delete_template(self, template: Template):
#         """ Deletes the template from the given cluster id      
#         :param 
#             index: cluster id
#         :return  
#             the cluster without the template
#         :raises 
#             IndexError: An error occurs if a negative cluster id is provided
#             or if the cluster id doesn't exist
#         """
#         key = template.get_length()
#         if key not in self.templates:
#             raise IndexError("No cluster with the giving id!")
# 
#         self.templates[key].remove(template)
# 
#     def number_of_clusters(self):
#         """ Get the number of clusters inside the chromosome
#         :return: 
#             an integer: number of cluster 
#         """
#         return len(self.templates.keys())
# 
#     def cluster_size(self, cluster_id: int):
#         """ Get the number of templates inside a given cluster
#         :return: 
#             an integer: number of templates 
#         """
#         return len(self.templates[cluster_id])
# 
#     def all_templates(self):
#         """ Returns the total number of templates of a chromosome
#         """
#         number_templates = 0
#         for key in self.templates.keys():
#             number_templates = number_templates + self.cluster_size(key)
#         return number_templates
# 
#     def to_string(self):
#         """ Prints the content of a chromosome
#        :return: all templates as a string 
#         """
#         s = ""
#         for list_t in self.templates.values():
#             for t in list_t:
# 
#                 s = s + t.to_string() + "\n"
#         return s
# 
# Path: logparser/MoLFI/main/org/core/chromosome/template.py
# class Template:
#     """ An object representing the smallest element of a chromosome which is a template
#         Template is a list of strings
#     """
# 
#     def __init__(self, p_template: List[str]):
#         """ The constructor of the Class Template
#         initialize the object with a list of strings
#         and initialize the frequency and specificity with 0.0
#         and an empty list that will contain the line number matching the template
#         """
#         self.token = p_template
#         self.specificity = 0.0
#         self.matched_lines = []
#         self.changed = True
# 
#     def get_length(self):
#         """ Gets the number of strings in the list    
#         """
#         return len(self.token)
# 
#     def to_string(self):
#         """ Returns the template's token as one string
#         """
#         s = "[ "
#         for i in self.token:
#             s = s+i+' '
# 
#         s = s + ']'
#         return s
# 
#     def is_changed(self):
#         """ Returns the status of the template (changed or did not change)
#         """
#         return self.changed
# 
#     def set_changed(self, p_changed : bool):
#         """ Sets the status of a template to True if one of its tokens changes,
#         else the status is False (not changed)
#         """
#         self.changed = p_changed


# Path: logparser/MoLFI/main/org/core/utility/chromosome_corrections.py
import random
from ..chromosome.chromosome import Chromosome
from ..chromosome.template import Template

    
    :param chromosome: the chromosome with the templates
    :param messages: the original log messages
    :return: possibly corrected templates
    """
    for key in chromosome.templates.keys():
        for template in chromosome.templates[key]:
            for index in range(0, len(template.token)):
                token = template.token[index]
                words = set([])
                # gets all values at position index from the matched lines
                if token == "*" or token == "#spec#":
                    for message_index in template.matched_lines:
                        message = messages[key][message_index]
                        words.add(message.words[index])
                    # if all matched lines have the same word,
                    # the star in the template will be replaced with that word
                    if len(words) == 1:
                        template.token[index] = words.pop()


def is_all_star_template(template: Template):
    has_no_star = False
    for token in template.token:
        if not (token == "*" or token.startswith("[") or token == "#spec#"):
            has_no_star = True
            break
    return not has_no_star



def fix_all_star_template(ch: Chromosome, cluster_id: int, template_index: int, messages: dict):
