import csv
import collections
from operator import itemgetter

class RepoLabelsClass:
   
    def __init__(self, r):
        self.repository = str(r)
        # Issue and Class size
        self.classifieldSize = ''
        
        # Labels usage flags
        self.isLabelingFirstPratice = False
        self.issuesAmount = 0
        # Amount of issues labeled
        self.labeledIssueAmount = 0 
        self.issuesLabeledFirstAmount = 0

        self.labelsRepo = []

        self.whenLabelingOccurs = []

    def repoClassification(self):
        if(self.issuesAmount > 142):
            if(self.issuesAmount > 546):
                self.classifieldSize = 'Biggest'
            else:
                self.classifieldSize = 'Bigger'
        else:
            if(self.issuesAmount < 35):
                 self.classifieldSize = 'Small'
            else:
                self.classifieldSize = 'Smallest'

    def mountLabelInfo(self, label):
        type = ''

        if(label in ["bug", "documentation", "duplicate", "enhancement", "good first issue", "help wanted", "invalid", "question", "wontfix"]):
            type = 'standard'
        else:
            type = 'custom'

        return {
            "Label": str(label),
            "Amount": 0,
            "Title_Related": 0,
            "Body_Related": 0,
            "Comment_Related": 0,
            "Type": str(type)
        }
    
    def labelExistsInList(self, label):
        for l in self.labelsRepo:
            if(label in l['Label']):
                return True
        
        return False



    def addLabel(self, labels, flag):
        for label in labels:
            label_search = next((x for x in self.labelsRepo if x["Label"] == label.lower()), None)

            if(label_search is None):
                label_registry = self.mountLabelInfo(label.lower())
                if(flag == 1):
                    label_registry['Amount'] += 1
                
                self.labelsRepo.append(label_registry)
                
            elif(label_search is not None):
                label_search['Amount'] += 1        
    
    def countLabelOccurrenceInIssue(self, label, component):
        label_search = next((x for x in self.labelsRepo if x["Label"] == label.lower()), None)

        if(component == 'Title'):
            label_search['Title_Related'] += 1
        elif(component == 'Body'):
            label_search['Body_Related'] += 1
        elif(component == 'Comment'):
            label_search['Comment_Related'] += 1
    
    def mount_event(self, issue, pos):
        return {'Issue' : int(issue), 'Pos': int(pos)}

    def countFirstLabelingEvent(self, issue, issue_events):
        event_counter = 1

        for e in issue_events:
            if(e['Event'] == 'labeled'):
                if(event_counter == 1):
                    self.issuesLabeledFirstAmount += 1
                
                #evnt = self.mount_event(issue, event_counter)
                self.whenLabelingOccurs.append(event_counter)
            event_counter += 1

    def countLabelOccurrencies(self, labels_list , title, body, comments):
        occurrences_in_title = 0
        occurrences_in_body  = 0
        occurrences_in_commentary = 0

        for label in labels_list:
            label_search = next((x for x in self.labelsRepo if x["Label"] == label.lower()), None)

            if(title is not None):
                occurrences_in_title += title.count(label)
            if(body is not None):
                occurrences_in_body += body.count(label)

            if(comments is not None):
                for c in comments:
                    occurrences_in_commentary += c.count(label)

            label_search['Title_Related']       += occurrences_in_title 
            label_search['Body_Related']        += occurrences_in_body
            label_search['Comment_Related']     += occurrences_in_commentary

    def savingGeneralStatistics(self):
        repository = self.repository                                                                        #[1]
        amountOfIssues = self.issuesAmount                                                                  #[2]
        classifield = self.classifieldSize                                                                  #[3]
        
        useLabels = 'No'                                                                                    #[4]
        if(self.labeledIssueAmount > 0):
            useLabels = 'Yes'
        
        amountOfIssuesLabeled = self.labeledIssueAmount                                                     #[5]
       
        useStandardLabel = 'No'                                                                             #[6]
        amountOfStandardLabelsUsed = 0                                                                      #[7]

        StandardLabel_list = sorted(list(filter(lambda l: l['Type'] == 'standard', self.labelsRepo)), key=itemgetter('Amount'), reverse=True)
        standardLabel_mostUsed = next((x for x in StandardLabel_list), None)
        
        standardLabel_mostUsed_Label = '-'
        standardLabel_mostUsed_Amount = '0'

        if(standardLabel_mostUsed is not None):
            if(standardLabel_mostUsed['Amount'] > 0):
                standardLabel_mostUsed_Label = standardLabel_mostUsed['Label']
                standardLabel_mostUsed_Amount = standardLabel_mostUsed['Amount']

        amountOfStandardLabelsUsed = sum([x['Amount'] for x in StandardLabel_list])

        if(amountOfStandardLabelsUsed > 0):
            useStandardLabel = 'Yes'

        # 9 labels

        AllStandardLabelsUsed = 'No'                                                                        #[8]

        UsageOfStandardLabel = list(filter(lambda l: l['Amount'] > 0, StandardLabel_list))
        if(UsageOfStandardLabel == 9):
            AllStandardLabelsUsed = 'Yes'

        createCustomLabels = 'No'                                                                           #[9]

        CustomLabel_list = list(filter(lambda l: l['Type'] == 'custom', self.labelsRepo))
        
        if(len(CustomLabel_list) > 0):
            createCustomLabels = 'Yes'

        amountOfCustomLabelsCreated = len(CustomLabel_list)                                                 #[10]
        useCustomLabels = 'No'                                                                              #[11]                      
        amountOfCustomLabelsUsed = sum([x['Amount'] for x in CustomLabel_list])                             #[12]

        CustomLabel_Usage = list(filter(lambda l: l['Amount'] > 0, CustomLabel_list))
        
        if(len(CustomLabel_Usage) > 0):
            useCustomLabels = 'Yes'

        useAllCustomLabel = 'No'                                                                            #[13]
        CustomLabelsUsed = len(CustomLabel_Usage)                                                           #[14]

        if(len(CustomLabel_list) == len(CustomLabel_Usage)):
            useAllCustomLabel = 'Yes'

        if(len(CustomLabel_list) == 0 and len(CustomLabel_Usage) == 0):
            useAllCustomLabel = 'No'

        repository_row = [repository,
                          amountOfIssues,   
                          classifield,
                          useLabels,
                          amountOfIssuesLabeled,
                          useStandardLabel,
                          amountOfStandardLabelsUsed,
                          AllStandardLabelsUsed,
                          standardLabel_mostUsed_Label,
                          standardLabel_mostUsed_Amount,
                          createCustomLabels,
                          amountOfCustomLabelsCreated,
                          useCustomLabels,
                          amountOfCustomLabelsUsed,
                          useAllCustomLabel,
                          CustomLabelsUsed
        ]
    
        with open('GeneralInfo.csv', mode='a') as GeneralInfo_csv:
            mount_generalInfo_csv = csv.writer(GeneralInfo_csv)
            mount_generalInfo_csv.writerow(repository_row)
        GeneralInfo_csv.close()

    def savingCustomLabelStatistics(self):
        
        CustomLabel_list = sorted(list(filter(lambda l: l['Type'] == 'custom', self.labelsRepo)), key=itemgetter('Amount'), reverse=True)
        registry_list = []

        registry_list.append(self.repository)

        for l in CustomLabel_list[:5]:
            registry_list.append(str(l['Label']))
            registry_list.append(str(l['Amount']))
        
        with open('CustomLabelsInfo.csv', mode='a') as CustomLabelInfo_CSV:
            mount_customLabelInfo_csv = csv.writer(CustomLabelInfo_CSV)
            mount_customLabelInfo_csv.writerow(registry_list)

        CustomLabelInfo_CSV.close()
    
    def WhenLabelingOccursStatistics(self):
        repository = self.repository
        isLabelingFirstPratice = 'No'

        event_labeling_most_occurs = collections.Counter(self.whenLabelingOccurs)
        
        ev1 = '-'
        ev2 = '-'
        if(len(event_labeling_most_occurs) > 0):
            event_most_occors_pos = event_labeling_most_occurs.most_common(1)[0]

            if(event_most_occors_pos[0] == 1):
                isLabelingFirstPratice = 'Yes'
            
            ev1 = event_most_occors_pos[0]
            ev2 = event_most_occors_pos[1]

        registry_line = [repository, 
                         isLabelingFirstPratice, 
                         self.issuesLabeledFirstAmount,
                         ev1,
                         ev2]

        with open('WhenLabelingOccursInfo.csv', mode='a') as WhenOccursInfo_csv:
            mount_whenOccursInfo_csv = csv.writer(WhenOccursInfo_csv)
            mount_whenOccursInfo_csv.writerow(registry_line)

        WhenOccursInfo_csv.close()

    def LabelRelatedStatus(self):
        repository = self.repository
        isTitleRelated      = 'No'
        isBodyRelated       = 'No'
        isCommentRelated    = 'No'

        Label_TitleRelated_list = list(filter(lambda l: l['Title_Related'] > 0, self.labelsRepo))
        Label_BodyRelated_list = list(filter(lambda l: l['Body_Related'] > 0, self.labelsRepo))
        Label_CommentRelated_list = list(filter(lambda l: l['Comment_Related'] > 0, self.labelsRepo))
        
        amountOfTitleRelated = sum([x['Title_Related'] for x in Label_TitleRelated_list])
        amountOfBodyRelated = sum([x['Body_Related'] for x in Label_BodyRelated_list])
        amountOfCommentRelated = sum([x['Comment_Related'] for x in Label_CommentRelated_list])

        Sorted_First_TitleRelated      = sorted(Label_TitleRelated_list, key=itemgetter('Title_Related'), reverse=True)
        Sorted_First_BodyRelated       = sorted(Label_BodyRelated_list, key=itemgetter('Body_Related'), reverse=True)
        Sorted_First_CommentRelated    = sorted(Label_CommentRelated_list, key=itemgetter('Comment_Related'), reverse=True)

        First_TitleRelated      = next((t for t in Sorted_First_TitleRelated), None)
        First_BodyRelated       = next((b for b in Sorted_First_BodyRelated), None)
        First_CommentRelated    = next((c for c in Sorted_First_CommentRelated), None)

        firstTitleLabel  = ''
        firstTitleNumber = 0
        firstBodyLabel = ''
        firstBodyNumber = 0
        firstCommentsLabel = ''
        firstCommentsNumber = 0

        if(First_TitleRelated is not None):
            firstTitleLabel  = First_TitleRelated['Label']
            firstTitleNumber = First_TitleRelated['Title_Related']
        
        if(First_BodyRelated is not None):
            firstBodyLabel = First_BodyRelated['Label']
            firstBodyNumber = First_BodyRelated['Body_Related']

        if(First_CommentRelated is not None):
            firstCommentsLabel = First_CommentRelated['Label']
            firstCommentsNumber = First_CommentRelated['Comment_Related']



        if(len(Label_TitleRelated_list) > 0):
            isTitleRelated = 'Yes'
        if(len(Label_BodyRelated_list) > 0):
            isBodyRelated = 'Yes'
        if(len(Label_CommentRelated_list) > 0):
            isCommentRelated = 'Yes'

        registry_line = [repository, 
                         isTitleRelated, 
                         amountOfTitleRelated, 
                         firstTitleLabel,
                         firstTitleNumber,
                         isBodyRelated,
                         amountOfBodyRelated,
                         firstBodyLabel,
                         firstBodyNumber,
                         isCommentRelated,
                         amountOfCommentRelated,
                         firstCommentsLabel,
                         firstCommentsNumber
                         ]


        with open('LabelRelated.csv', mode='a') as LabelRelatedInfo_csv:
            mount_labelRelated_csv = csv.writer(LabelRelatedInfo_csv)
            mount_labelRelated_csv.writerow(registry_line)
            
        LabelRelatedInfo_csv.close()
