#!/bin/env python3
import argparse
import json
import os
import re
import yaml

from sh import git  # type: ignore
from typing import List, Set, TypedDict, Optional
from yaml.loader import SafeLoader

# A list of Gerrit users (email addresses).
#   Some OWNERS files have empty lists for 'owners' or 'reviewers', which
#   results in a None type for the value.
UsersList = Optional[List[str]]

# A YAML node with an extra line number.
class NumberedNode(TypedDict):
    line_number: int


class MatchEntry(TypedDict, total=False):
    suffix: str
    regex: str
    partial_regex: str
    exact: str
    owners: UsersList
    reviewers: UsersList


# The root YAML node of an OWNERS file
class OwnersData(NumberedNode, TypedDict, total=False):
    owners: UsersList
    reviewers: UsersList
    matchers: List[MatchEntry]


# A YAML loader that adds the start line number onto each node (for
# later linting support)
class YamlLoader(SafeLoader):
    def construct_mapping(
        self, node: yaml.nodes.Node, deep: bool = False
    ) -> NumberedNode:
        mapping: NumberedNode = super(YamlLoader, self).construct_mapping(
            node, deep=deep
        )  # type: ignore
        mapping["line_number"] = node.start_mark.line + 1
        return mapping

    # Load a file and return the OwnersData.
    @staticmethod
    def load(file: str) -> OwnersData:
        data: OwnersData
        with open(file, "r") as f:
            data = yaml.load(f, Loader=YamlLoader)
        return data


# Class to match commit information with OWNERS files.
class CommitMatch:
    def __init__(self, args: argparse.Namespace, owners: OwnersData):
        files: Set[str] = set(
            git.bake("-C", args.path)
            .show(args.commit, pretty="", name_only=True, _tty_out=False)
            .splitlines()
        )

        self.owners: Set[str] = set(owners.get("owners") or [])
        self.reviewers: Set[str] = set(owners.get("reviewers") or [])

        for e in owners.get("matchers", None) or []:
            if "exact" in e:
                self.__exact(files, e)
            elif "partial_regex" in e:
                self.__partial_regex(files, e)
            elif "regex" in e:
                self.__regex(files, e)
            elif "suffix" in e:
                self.__suffix(files, e)

        self.reviewers = self.reviewers.difference(self.owners)

    def __add_entry(self, entry: MatchEntry) -> None:
        self.owners = self.owners.union(entry.get("owners") or [])
        self.reviewers = self.reviewers.union(entry.get("reviewers") or [])

    def __exact(self, files: Set[str], entry: MatchEntry) -> None:
        for f in files:
            if f == entry["exact"]:
                self.__add_entry(entry)

    def __partial_regex(self, files: Set[str], entry: MatchEntry) -> None:
        for f in files:
            if re.search(entry["partial_regex"], f):
                self.__add_entry(entry)

    def __regex(self, files: Set[str], entry: MatchEntry) -> None:
        for f in files:
            if re.fullmatch(entry["regex"], f):
                self.__add_entry(entry)

    def __suffix(self, files: Set[str], entry: MatchEntry) -> None:
        for f in files:
            if os.path.splitext(f)[1] == entry["suffix"]:
                self.__add_entry(entry)


# The subcommand to get the reviewers.
def subcmd_reviewers(args: argparse.Namespace, data: OwnersData) -> None:
    matcher = CommitMatch(args, data)

    # Print in `git push refs/for/branch%<reviewers>` format.
    if args.push_args:
        result = []
        for o in sorted(matcher.owners):
            # Gerrit uses 'r' for the required reviewers (owners).
            result.append(f"r={o}")
        for r in sorted(matcher.reviewers):
            # Gerrit uses 'cc' for the optional reviewers.
            result.append(f"cc={r}")
        print(",".join(result))
    # Print as Gerrit Add Reviewers POST format.
    # https://gerrit.openbmc.org/Documentation/rest-api-changes.html#add-reviewer
    else:
        for o in sorted(matcher.owners):
            print(json.dumps({"reviewer": o, "state": "REVIEWER"}))
        for r in sorted(matcher.reviewers):
            print(json.dumps({"reviewer": r, "state": "CC"}))


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-p", "--path", default=".", help="Root path to analyse"
    )
    subparsers = parser.add_subparsers()

    parser_reviewers = subparsers.add_parser(
        "reviewers", help="Generate List of Reviewers"
    )
    parser_reviewers.add_argument(
        "--push-args",
        default=False,
        action='store_true',
        help="Format as git push options",
    )
    parser_reviewers.add_argument(
        "--commit",
        default="HEAD",
        help="Commit(s) to match against",
    )
    parser_reviewers.set_defaults(func=subcmd_reviewers)

    args = parser.parse_args()

    file = YamlLoader.load(args.path + "/OWNERS")
    args.func(args, file)


if __name__ == "__main__":
    main()
