## @file
#  Retrieves the people to request review from on submission of a commit.
#
#  Copyright (c) 2019, Linaro Ltd. All rights reserved.<BR>
#
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#

from __future__ import print_function
from collections import defaultdict
from collections import OrderedDict
import argparse
import os
import re
import SetupGit

EXPRESSIONS = {
    'exclude':    re.compile(r'^X:\s*(?P<exclude>.*?)\r*$'),
    'file':       re.compile(r'^F:\s*(?P<file>.*?)\r*$'),
    'list':       re.compile(r'^L:\s*(?P<list>.*?)\r*$'),
    'maintainer': re.compile(r'^M:\s*(?P<maintainer>.*?)\r*$'),
    'reviewer':   re.compile(r'^R:\s*(?P<reviewer>.*?)\r*$'),
    'status':     re.compile(r'^S:\s*(?P<status>.*?)\r*$'),
    'tree':       re.compile(r'^T:\s*(?P<tree>.*?)\r*$'),
    'webpage':    re.compile(r'^W:\s*(?P<webpage>.*?)\r*$')
}

def printsection(section):
    """Prints out the dictionary describing a Maintainers.txt section."""
    print('===')
    for key in section.keys():
        print("Key: %s" % key)
        for item in section[key]:
            print('  %s' % item)

def pattern_to_regex(pattern):
    """Takes a string containing regular UNIX path wildcards
       and returns a string suitable for matching with regex."""

    pattern = pattern.replace('.', r'\.')
    pattern = pattern.replace('?', r'.')
    pattern = pattern.replace('*', r'.*')

    if pattern.endswith('/'):
        pattern += r'.*'
    elif pattern.endswith('.*'):
        pattern = pattern[:-2]
        pattern += r'(?!.*?/.*?)'

    return pattern

def path_in_section(path, section):
    """Returns True of False indicating whether the path is covered by
       the current section."""
    if not 'file' in section:
        return False

    for pattern in section['file']:
        regex = pattern_to_regex(pattern)

        match = re.match(regex, path)
        if match:
            # Check if there is an exclude pattern that applies
            for pattern in section['exclude']:
                regex = pattern_to_regex(pattern)

                match = re.match(regex, path)
                if match:
                    return False

            return True

    return False

def get_section_maintainers(path, section):
    """Returns a list with email addresses to any M: and R: entries
       matching the provided path in the provided section."""
    maintainers = []
    reviewers = []
    lists = []
    nowarn_status = ['Supported', 'Maintained']

    if path_in_section(path, section):
        for status in section['status']:
            if status not in nowarn_status:
                print('WARNING: Maintained status for "%s" is \'%s\'!' % (path, status))
        for address in section['maintainer']:
            # Convert to list if necessary
            if isinstance(address, list):
                maintainers += address
            else:
                maintainers += [address]
        for address in section['reviewer']:
            # Convert to list if necessary
            if isinstance(address, list):
                reviewers += address
            else:
                reviewers += [address]
        for address in section['list']:
            # Convert to list if necessary
            if isinstance(address, list):
                lists += address
            else:
                lists += [address]

    return {'maintainers': maintainers, 'reviewers': reviewers, 'lists': lists}

def get_maintainers(path, sections, level=0):
    """For 'path', iterates over all sections, returning maintainers
       for matching ones."""
    maintainers = []
    reviewers = []
    lists = []
    for section in sections:
        recipients = get_section_maintainers(path, section)
        maintainers += recipients['maintainers']
        reviewers += recipients['reviewers']
        lists += recipients['lists']

    if not maintainers:
        # If no match found, look for match for (nonexistent) file
        # REPO.working_dir/<default>
        print('"%s": no maintainers found, looking for default' % path)
        if level == 0:
            recipients = get_maintainers('<default>', sections, level=level + 1)
            maintainers += recipients['maintainers']
            reviewers += recipients['reviewers']
            lists += recipients['lists']
        else:
            print("No <default> maintainers set for project.")
        if not maintainers:
            return None

    return {'maintainers': maintainers, 'reviewers': reviewers, 'lists': lists}

def parse_maintainers_line(line):
    """Parse one line of Maintainers.txt, returning any match group and its key."""
    for key, expression in EXPRESSIONS.items():
        match = expression.match(line)
        if match:
            return key, match.group(key)
    return None, None

def parse_maintainers_file(filename):
    """Parse the Maintainers.txt from top-level of repo and
       return a list containing dictionaries of all sections."""
    with open(filename, 'r') as text:
        line = text.readline()
        sectionlist = []
        section = defaultdict(list)
        while line:
            key, value = parse_maintainers_line(line)
            if key and value:
                section[key].append(value)

            line = text.readline()
            # If end of section (end of file, or non-tag line encountered)...
            if not key or not value or not line:
                # ...if non-empty, append section to list.
                if section:
                    sectionlist.append(section.copy())
                    section.clear()

        return sectionlist

def get_modified_files(repo, args):
    """Returns a list of the files modified by the commit specified in 'args'."""
    commit = repo.commit(args.commit)
    return commit.stats.files

if __name__ == '__main__':
    PARSER = argparse.ArgumentParser(
        description='Retrieves information on who to cc for review on a given commit')
    PARSER.add_argument('commit',
                        action="store",
                        help='git revision to examine (default: HEAD)',
                        nargs='?',
                        default='HEAD')
    PARSER.add_argument('-l', '--lookup',
                        help='Find section matches for path LOOKUP',
                        required=False)
    PARSER.add_argument('-g', '--github',
                        action='store_true',
                        help='Include GitHub usernames in output',
                        required=False)
    ARGS = PARSER.parse_args()

    REPO = SetupGit.locate_repo()

    CONFIG_FILE = os.path.join(REPO.working_dir, 'Maintainers.txt')

    SECTIONS = parse_maintainers_file(CONFIG_FILE)

    if ARGS.lookup:
        FILES = [ARGS.lookup.replace('\\','/')]
    else:
        FILES = get_modified_files(REPO, ARGS)

    # Accumulate a sorted list of addresses
    ADDRESSES = set([])
    for file in FILES:
        print(file)
        recipients = get_maintainers(file, SECTIONS)
        ADDRESSES |= set(recipients['maintainers'] + recipients['reviewers'] + recipients['lists'])
    ADDRESSES = list(ADDRESSES)
    ADDRESSES.sort()

    for address in ADDRESSES:
        if '<' in address and '>' in address:
            address, github_id = address.split('>', 1)
            address = address + '>'
            github_id = github_id.strip() if ARGS.github else ''

        print('  %s %s' % (address, github_id))
