## @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 = []
    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'], section['reviewer']:
            # Convert to list if necessary
            if isinstance(address, list):
                maintainers += address
            else:
                lists += [address]
        for address in section['list']:
            # Convert to list if necessary
            if isinstance(address, list):
                lists += address
            else:
                lists += [address]

    return maintainers, lists

def get_maintainers(path, sections, level=0):
    """For 'path', iterates over all sections, returning maintainers
       for matching ones."""
    maintainers = []
    lists = []
    for section in sections:
        tmp_maint, tmp_lists = get_section_maintainers(path, section)
        if tmp_maint:
            maintainers += tmp_maint
        if tmp_lists:
            lists += tmp_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:
            maintainers = get_maintainers('<default>', sections, level=level + 1)
        else:
            print("No <default> maintainers set for project.")
        if not maintainers:
            return None

    return maintainers + 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)
    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)

    ADDRESSES = []

    for file in FILES:
        print(file)
        addresslist = get_maintainers(file, SECTIONS)
        if addresslist:
            ADDRESSES += addresslist

    for address in list(OrderedDict.fromkeys(ADDRESSES)):
        if '<' in address and '>' in address:
            address = address.split('>', 1)[0] + '>'
        print('  %s' % address)
