#!/usr/bin/env python3

# Copyright (c) 2019 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

"""
Lists maintainers for files or commits. Similar in function to
scripts/get_maintainer.pl from Linux, but geared towards GitHub. The mapping is
in MAINTAINERS.yml.

The comment at the top of MAINTAINERS.yml in Zephyr documents the file format.

See the help texts for the various subcommands for more information. They can
be viewed with e.g.

    ./get_maintainer.py path --help

This executable doubles as a Python library. Identifiers not prefixed with '_'
are part of the library API. The library documentation can be viewed with this
command:

    $ pydoc get_maintainer
"""

import argparse
import operator
import os
import pathlib
import re
import shlex
import subprocess
import sys

from yaml import load, YAMLError
try:
    # Use the speedier C LibYAML parser if available
    from yaml import CLoader as Loader
except ImportError:
    from yaml import Loader


def _main():
    # Entry point when run as an executable

    args = _parse_args()
    try:
        args.cmd_fn(Maintainers(args.maintainers), args)
    except (MaintainersError, GitError) as e:
        _serr(e)


def _parse_args():
    # Parses arguments when run as an executable

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=__doc__)

    parser.add_argument(
        "-m", "--maintainers",
        metavar="MAINTAINERS_FILE",
        help="Maintainers file to load. If not specified, MAINTAINERS.yml in "
             "the top-level repository directory is used, and must exist. "
             "Paths in the maintainers file will always be taken as relative "
             "to the top-level directory.")

    subparsers = parser.add_subparsers(
        help="Available commands (each has a separate --help text)")

    id_parser = subparsers.add_parser(
        "path",
        help="List area(s) for paths")
    id_parser.add_argument(
        "paths",
        metavar="PATH",
        nargs="*",
        help="Path to list areas for")
    id_parser.set_defaults(cmd_fn=Maintainers._path_cmd)

    commits_parser = subparsers.add_parser(
        "commits",
        help="List area(s) for commit range")
    commits_parser.add_argument(
        "commits",
        metavar="COMMIT_RANGE",
        nargs="*",
        help="Commit range to list areas for (default: HEAD~..)")
    commits_parser.set_defaults(cmd_fn=Maintainers._commits_cmd)

    list_parser = subparsers.add_parser(
        "list",
        help="List files in areas")
    list_parser.add_argument(
        "area",
        metavar="AREA",
        nargs="?",
        help="Name of area to list files in. If not specified, all "
             "non-orphaned files are listed (all files that do not appear in "
             "any area).")
    list_parser.set_defaults(cmd_fn=Maintainers._list_cmd)

    areas_parser = subparsers.add_parser(
        "areas",
        help="List areas and maintainers")
    areas_parser.add_argument(
        "maintainer",
        metavar="MAINTAINER",
        nargs="?",
        help="List all areas maintained by maintaier.")

    areas_parser.set_defaults(cmd_fn=Maintainers._areas_cmd)

    orphaned_parser = subparsers.add_parser(
        "orphaned",
        help="List orphaned files (files that do not appear in any area)")
    orphaned_parser.add_argument(
        "path",
        metavar="PATH",
        nargs="?",
        help="Limit to files under PATH")
    orphaned_parser.set_defaults(cmd_fn=Maintainers._orphaned_cmd)

    args = parser.parse_args()
    if not hasattr(args, "cmd_fn"):
        # Called without a subcommand
        sys.exit(parser.format_usage().rstrip())

    return args


class Maintainers:
    """
    Represents the contents of a maintainers YAML file.

    These attributes are available:

    areas:
        A dictionary that maps area names to Area instances, for all areas
        defined in the maintainers file

    filename:
        The path to the maintainers file
    """
    def __init__(self, filename=None):
        """
        Creates a Maintainers instance.

        filename (default: None):
            Path to the maintainers file to parse. If None, MAINTAINERS.yml in
            the top-level directory of the Git repository is used, and must
            exist.
        """
        self._toplevel = pathlib.Path(_git("rev-parse", "--show-toplevel"))

        if filename is None:
            self.filename = self._toplevel / "MAINTAINERS.yml"
        else:
            self.filename = pathlib.Path(filename)

        self.areas = {}
        for area_name, area_dict in _load_maintainers(self.filename).items():
            area = Area()
            area.name = area_name
            area.status = area_dict.get("status")
            area.maintainers = area_dict.get("maintainers", [])
            area.collaborators = area_dict.get("collaborators", [])
            area.inform = area_dict.get("inform", [])
            area.labels = area_dict.get("labels", [])
            area.description = area_dict.get("description")

            # area._match_fn(path) tests if the path matches files and/or
            # files-regex
            area._match_fn = \
                _get_match_fn(area_dict.get("files"),
                              area_dict.get("files-regex"))

            # Like area._match_fn(path), but for files-exclude and
            # files-regex-exclude
            area._exclude_match_fn = \
                _get_match_fn(area_dict.get("files-exclude"),
                              area_dict.get("files-regex-exclude"))

            self.areas[area_name] = area

    def path2areas(self, path):
        """
        Returns a list of Area instances for the areas that contain 'path',
        taken as relative to the current directory
        """
        # Make directory paths end in '/' so that foo/bar matches foo/bar/.
        # Skip this check in _contains() itself, because the isdir() makes it
        # twice as slow in cases where it's not needed.
        is_dir = os.path.isdir(path)

        # Make 'path' relative to the repository root and normalize it.
        # normpath() would remove a trailing '/', so we add it afterwards.
        path = os.path.normpath(os.path.join(
            os.path.relpath(os.getcwd(), self._toplevel),
            path))

        if is_dir:
            path += "/"

        return [area for area in self.areas.values()
                if area._contains(path)]

    def commits2areas(self, commits):
        """
        Returns a set() of Area instances for the areas that contain files that
        are modified by the commit range in 'commits'. 'commits' could be e.g.
        "HEAD~..", to inspect the tip commit
        """
        res = set()
        # Final '--' is to make sure 'commits' is interpreted as a commit range
        # rather than a path. That might give better error messages.
        for path in _git("diff", "--name-only", commits, "--").splitlines():
            res.update(self.path2areas(path))
        return res

    def __repr__(self):
        return "<Maintainers for '{}'>".format(self.filename)

    #
    # Command-line subcommands
    #

    def _path_cmd(self, args):
        # 'path' subcommand implementation

        for path in args.paths:
            if not os.path.exists(path):
                _serr("'{}': no such file or directory".format(path))

        res = set()
        orphaned = []
        for path in args.paths:
            areas = self.path2areas(path)
            res.update(areas)
            if not areas:
                orphaned.append(path)

        _print_areas(res)
        if orphaned:
            if res:
                print()
            print("Orphaned paths (not in any area):\n" + "\n".join(orphaned))

    def _commits_cmd(self, args):
        # 'commits' subcommand implementation

        commits = args.commits or ("HEAD~..",)
        _print_areas({area for commit_range in commits
                           for area in self.commits2areas(commit_range)})

    def _areas_cmd(self, args):
        # 'areas' subcommand implementation
        for area in self.areas.values():
            if args.maintainer:
                if args.maintainer in area.maintainers:
                    print("{:25}\t{}".format(area.name, ",".join(area.maintainers)))
            else:
                print("{:25}\t{}".format(area.name, ",".join(area.maintainers)))

    def _list_cmd(self, args):
        # 'list' subcommand implementation

        if args.area is None:
            # List all files that appear in some area
            for path in _ls_files():
                for area in self.areas.values():
                    if area._contains(path):
                        print(path)
                        break
        else:
            # List all files that appear in the given area
            area = self.areas.get(args.area)
            if area is None:
                _serr("'{}': no such area defined in '{}'"
                      .format(args.area, self.filename))

            for path in _ls_files():
                if area._contains(path):
                    print(path)

    def _orphaned_cmd(self, args):
        # 'orphaned' subcommand implementation

        if args.path is not None and not os.path.exists(args.path):
            _serr("'{}': no such file or directory".format(args.path))

        for path in _ls_files(args.path):
            for area in self.areas.values():
                if area._contains(path):
                    break
            else:
                print(path)  # We get here if we never hit the 'break'


class Area:
    """
    Represents an entry for an area in MAINTAINERS.yml.

    These attributes are available:

    status:
        The status of the area, as a string. None if the area has no 'status'
        key. See MAINTAINERS.yml.

    maintainers:
        List of maintainers. Empty if the area has no 'maintainers' key.

    collaborators:
        List of collaborators. Empty if the area has no 'collaborators' key.

    inform:
        List of people to inform on pull requests. Empty if the area has no
        'inform' key.

    labels:
        List of GitHub labels for the area. Empty if the area has no 'labels'
        key.

    description:
        Text from 'description' key, or None if the area has no 'description'
        key
    """
    def _contains(self, path):
        # Returns True if the area contains 'path', and False otherwise

        return self._match_fn and self._match_fn(path) and not \
            (self._exclude_match_fn and self._exclude_match_fn(path))

    def __repr__(self):
        return "<Area {}>".format(self.name)


def _print_areas(areas):
    first = True
    for area in sorted(areas, key=operator.attrgetter("name")):
        if not first:
            print()
        first = False

        print("""\
{}
\tstatus: {}
\tmaintainers: {}
\tcollaborators: {}
\tinform: {}
\tlabels: {}
\tdescription: {}""".format(area.name,
                            area.status,
                            ", ".join(area.maintainers),
                            ", ".join(area.collaborators),
                            ", ".join(area.inform),
                            ", ".join(area.labels),
                            area.description or ""))


def _get_match_fn(globs, regexes):
    # Constructs a single regex that tests for matches against the globs in
    # 'globs' and the regexes in 'regexes'. Parts are joined with '|' (OR).
    # Returns the search() method of the compiled regex.
    #
    # Returns None if there are neither globs nor regexes, which should be
    # interpreted as no match.

    if not (globs or regexes):
        return None

    regex = ""

    if globs:
        glob_regexes = []
        for glob in globs:
            # Construct a regex equivalent to the glob
            glob_regex = glob.replace(".", "\\.").replace("*", "[^/]*") \
                             .replace("?", "[^/]")

            if not glob.endswith("/"):
                # Require a full match for globs that don't end in /
                glob_regex += "$"

            glob_regexes.append(glob_regex)

        # The glob regexes must anchor to the beginning of the path, since we
        # return search(). (?:) is a non-capturing group.
        regex += "^(?:{})".format("|".join(glob_regexes))

    if regexes:
        if regex:
            regex += "|"
        regex += "|".join(regexes)

    return re.compile(regex).search


def _load_maintainers(path):
    # Returns the parsed contents of the maintainers file 'filename', also
    # running checks on the contents. The returned format is plain Python
    # dicts/lists/etc., mirroring the structure of the file.

    with open(path, encoding="utf-8") as f:
        try:
            yaml = load(f, Loader=Loader)
        except YAMLError as e:
            raise MaintainersError("{}: YAML error: {}".format(path, e))

        _check_maintainers(path, yaml)
        return yaml


def _check_maintainers(maints_path, yaml):
    # Checks the maintainers data in 'yaml', which comes from the maintainers
    # file at maints_path, which is a pathlib.Path instance

    root = maints_path.parent

    def ferr(msg):
        _err("{}: {}".format(maints_path, msg))  # Prepend the filename

    if not isinstance(yaml, dict):
        ferr("empty or malformed YAML (not a dict)")

    ok_keys = {"status", "maintainers", "collaborators", "inform", "files",
               "files-exclude", "files-regex", "files-regex-exclude",
               "labels", "description"}

    ok_status = {"maintained", "odd fixes", "orphaned", "obsolete"}
    ok_status_s = ", ".join('"' + s + '"' for s in ok_status)  # For messages

    for area_name, area_dict in yaml.items():
        if not isinstance(area_dict, dict):
            ferr("malformed entry for area '{}' (not a dict)"
                 .format(area_name))

        for key in area_dict:
            if key not in ok_keys:
                ferr("unknown key '{}' in area '{}'"
                     .format(key, area_name))

        if "status" in area_dict and \
           area_dict["status"] not in ok_status:
            ferr("bad 'status' key on area '{}', should be one of {}"
                 .format(area_name, ok_status_s))

        if not area_dict.keys() & {"files", "files-regex"}:
            ferr("either 'files' or 'files-regex' (or both) must be specified "
                 "for area '{}'".format(area_name))

        for list_name in "maintainers", "collaborators", "inform", "files", \
                         "files-regex", "labels":
            if list_name in area_dict:
                lst = area_dict[list_name]
                if not (isinstance(lst, list) and
                        all(isinstance(elm, str) for elm in lst)):
                    ferr("malformed '{}' value for area '{}' -- should "
                         "be a list of strings".format(list_name, area_name))

        for files_key in "files", "files-exclude":
            if files_key in area_dict:
                for glob_pattern in area_dict[files_key]:
                    # This could be changed if it turns out to be too slow,
                    # e.g. to only check non-globbing filenames. The tuple() is
                    # needed due to pathlib's glob() returning a generator.
                    paths = tuple(root.glob(glob_pattern))
                    if not paths:
                        ferr("glob pattern '{}' in '{}' in area '{}' does not "
                             "match any files".format(glob_pattern, files_key,
                                                      area_name))
                    if not glob_pattern.endswith("/"):
                        for path in paths:
                            if path.is_dir():
                                ferr("glob pattern '{}' in '{}' in area '{}' "
                                     "matches a directory, but has no "
                                     "trailing '/'"
                                     .format(glob_pattern, files_key,
                                             area_name))

        for files_regex_key in "files-regex", "files-regex-exclude":
            if files_regex_key in area_dict:
                for regex in area_dict[files_regex_key]:
                    try:
                        re.compile(regex)
                    except re.error as e:
                        ferr("bad regular expression '{}' in '{}' in "
                             "'{}': {}".format(regex, files_regex_key,
                                               area_name, e.msg))

        if "description" in area_dict and \
           not isinstance(area_dict["description"], str):
            ferr("malformed 'description' value for area '{}' -- should be a "
                 "string".format(area_name))


def _git(*args):
    # Helper for running a Git command. Returns the rstrip()ed stdout output.
    # Called like git("diff"). Exits with SystemError (raised by sys.exit()) on
    # errors.

    git_cmd = ("git",) + args
    git_cmd_s = " ".join(shlex.quote(word) for word in git_cmd)  # For errors

    try:
        git_process = subprocess.Popen(
            git_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    except FileNotFoundError:
        _giterr("git executable not found (when running '{}'). Check that "
                "it's in listed in the PATH environment variable"
                .format(git_cmd_s))
    except OSError as e:
        _giterr("error running '{}': {}".format(git_cmd_s, e))

    stdout, stderr = git_process.communicate()
    if git_process.returncode:
        _giterr("error running '{}'\n\nstdout:\n{}\nstderr:\n{}".format(
            git_cmd_s, stdout.decode("utf-8"), stderr.decode("utf-8")))

    return stdout.decode("utf-8").rstrip()


def _ls_files(path=None):
    cmd = ["ls-files"]
    if path is not None:
        cmd.append(path)
    return _git(*cmd).splitlines()


def _err(msg):
    raise MaintainersError(msg)


def _giterr(msg):
    raise GitError(msg)


def _serr(msg):
    # For reporting errors when get_maintainer.py is run as a script.
    # sys.exit() shouldn't be used otherwise.
    sys.exit("{}: error: {}".format(sys.argv[0], msg))


class MaintainersError(Exception):
    "Exception raised for MAINTAINERS.yml-related errors"


class GitError(Exception):
    "Exception raised for Git-related errors"


if __name__ == "__main__":
    _main()
