## @file
#  GitHub API helper functions.
#
#  Copyright (c) Microsoft Corporation.
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#

import git
import logging
import os
import re

from collections import OrderedDict
from edk2toollib.utility_functions import RunPythonScript
from github import Auth, Github, GithubException
from io import StringIO
from typing import List


"""GitHub API helper functions."""


def _authenticate(token: str):
    """Authenticate to GitHub using a token.

    Returns a GitHub instance that is authenticated using the provided
    token.

    Args:
        token (str): The GitHub token to use for authentication.

    Returns:
        Github: A GitHub instance.
    """
    auth = Auth.Token(token)
    return Github(auth=auth)


def _get_pr(token: str, owner: str, repo: str, pr_number: int):
    """Get the PR object from GitHub.

    Args:
        token (str): The GitHub token to use for authentication.
        owner (str): The GitHub owner (organization) name.
        repo (str): The GitHub repository name (e.g. 'edk2').
        pr_number (int): The pull request number.

    Returns:
        PullRequest: A PyGithub PullRequest object for the given pull request
                     or None if the attempt to get the PR fails.
    """
    try:
        g = _authenticate(token)
        return g.get_repo(f"{owner}/{repo}").get_pull(pr_number)
    except GithubException as ge:
        print(
            f"::error title=Error Getting PR {pr_number} Info!::"
            f"{ge.data['message']}"
        )
        return None


def leave_pr_comment(
    token: str, owner: str, repo: str, pr_number: int, comment_body: str
):
    """Leaves a comment on a PR.

    Args:
        token (str): The GitHub token to use for authentication.
        owner (str): The GitHub owner (organization) name.
        repo (str): The GitHub repository name (e.g. 'edk2').
        pr_number (int): The pull request number.
        comment_body (str): The comment text. Markdown is supported.
    """
    if pr := _get_pr(token, owner, repo, pr_number):
        try:
            pr.create_issue_comment(comment_body)
        except GithubException as ge:
            print(
                f"::error title=Error Commenting on PR {pr_number}!::"
                f"{ge.data['message']}"
            )


def get_reviewers_for_range(
    workspace_path: str,
    maintainer_file_path: str,
    range_start: str = "master",
    range_end: str = "HEAD",
) -> List[str]:
    """Get the reviewers for the current branch.

    !!! note
        This function accepts a range of commits and returns the reviewers
        for that set of commits as a single list of GitHub usernames. To get
        the reviewers for a single commit, set `range_start` and `range_end`
        to the commit SHA.

    Args:
        workspace_path (str): The workspace path.
        maintainer_file_path (str): The maintainer file path.
        range_start (str, optional): The range start ref. Defaults to "master".
        range_end (str, optional): The range end ref. Defaults to "HEAD".

    Returns:
        List[str]: A list of GitHub usernames.
    """
    if range_start == range_end:
        commits = [range_start]
    else:
        commits = [
            c.hexsha
            for c in git.Repo(workspace_path).iter_commits(
                f"{range_start}..{range_end}"
            )
        ]

    raw_reviewers = []
    for commit_sha in commits:
        reviewer_stream_buffer = StringIO()
        cmd_ret = RunPythonScript(
            maintainer_file_path,
            f"-g {commit_sha}",
            workingdir=workspace_path,
            outstream=reviewer_stream_buffer,
            logging_level=logging.INFO,
        )
        if cmd_ret != 0:
            print(
                f"::error title=Reviewer Lookup Error!::Error calling "
                f"GetMaintainer.py: [{cmd_ret}]: "
                f"{reviewer_stream_buffer.getvalue()}"
            )
            return []

        commit_reviewers = reviewer_stream_buffer.getvalue()

        pattern = r"\[(.*?)\]"
        matches = re.findall(pattern, commit_reviewers)
        if not matches:
            return []

        print(
            f"::debug title=Commit {commit_sha[:7]} "
            f"Reviewer(s)::{', '.join(matches)}"
        )

        raw_reviewers.extend(matches)

    reviewers = list(OrderedDict.fromkeys([r.strip() for r in raw_reviewers]))

    print(f"::debug title=Total Reviewer Set::{', '.join(reviewers)}")

    return reviewers


def get_pr_sha(token: str, owner: str, repo: str, pr_number: int) -> str:
    """Returns the commit SHA of given PR branch.

    This returns the SHA of the merge commit that GitHub creates from a
    PR branch. This commit contains all of the files in the PR branch in
    a single commit.

    Args:
        token (str): The GitHub token to use for authentication.
        owner (str): The GitHub owner (organization) name.
        repo (str): The GitHub repository name (e.g. 'edk2').
        pr_number (int): The pull request number.

    Returns:
        str: The commit SHA of the PR branch. An empty string is returned
             if the request fails.
    """
    if pr := _get_pr(token, owner, repo, pr_number):
        merge_commit_sha = pr.merge_commit_sha
        print(f"::debug title=PR {pr_number} Merge Commit SHA::{merge_commit_sha}")
        return merge_commit_sha

    return ""


def add_reviewers_to_pr(
    token: str, owner: str, repo: str, pr_number: int, user_names: List[str]
) -> List[str]:
    """Adds the set of GitHub usernames as reviewers to the PR.

    Args:
        token (str): The GitHub token to use for authentication.
        owner (str): The GitHub owner (organization) name.
        repo (str): The GitHub repository name (e.g. 'edk2').
        pr_number (int): The pull request number.
        user_names (List[str]): List of GitHub usernames to add as reviewers.

    Returns:
        List[str]: A list of GitHub usernames that were successfully added as
                   reviewers to the PR. This list will exclude any reviewers
                   from the list provided if they are not relevant to the PR.
    """
    if not user_names:
        print(
            "::debug title=No PR Reviewers Requested!::"
            "The list of PR reviewers is empty so not adding any reviewers."
        )
        return []

    try:
        g = _authenticate(token)
        repo_gh = g.get_repo(f"{owner}/{repo}")
        pr = repo_gh.get_pull(pr_number)
    except GithubException as ge:
        print(
            f"::error title=Error Getting PR {pr_number} Info!::"
            f"{ge.data['message']}"
        )
        return None

    # The pull request author cannot be a reviewer.
    pr_author = pr.user.login.strip()

    # The current PR reviewers do not need to be requested again.
    current_pr_requested_reviewers = [
        r.login.strip() for r in pr.get_review_requests()[0] if r
    ]
    current_pr_reviewed_reviewers = [
        r.user.login.strip() for r in pr.get_reviews() if r and r.user
    ]
    current_pr_reviewers = list(
        set(current_pr_requested_reviewers + current_pr_reviewed_reviewers)
    )

    # A user can only be added if they are a collaborator of the repository.
    repo_collaborators = [c.login.strip().lower() for c in repo_gh.get_collaborators() if c]
    non_collaborators = [u for u in user_names if u.lower() not in repo_collaborators]

    excluded_pr_reviewers = {
        e.lower()
        for e in [pr_author] + current_pr_reviewers + non_collaborators
    }
    new_pr_reviewers = [
        u for u in user_names if u.lower() not in excluded_pr_reviewers
    ]

    # Notify the admins of the repository if non-collaborators are requested.
    if non_collaborators:
        print(
            f"::warning title=Non-Collaborator Reviewers Found!::"
            f"{', '.join(non_collaborators)}"
        )

        for comment in pr.get_issue_comments():
            # If a comment has already been made for these non-collaborators,
            # do not make another comment.
            if (
                comment.user
                and comment.user.login == "tianocore-assign-reviewers[bot]"
                and "WARNING: Cannot add some reviewers" in comment.body
                and all(u in comment.body for u in non_collaborators)
            ):
                break
        else:
            repo_admins = [
                a.login for a in repo_gh.get_collaborators(permission="admin") if a
            ]

            leave_pr_comment(
                token,
                owner,
                repo,
                pr_number,
                f"&#9888; **WARNING: Cannot add some reviewers**: A user  "
                f"specified as a reviewer for this PR is not a collaborator "
                f"of the repository. Please add them as a collaborator to "
                f"the repository so they can be requested in the future.\n\n"
                f"Non-collaborators requested:\n"
                f"{'\n'.join([f'- @{c}' for c in non_collaborators])}"
                f"\n\nAttn Admins:\n"
                f"{'\n'.join([f'- @{a}' for a in repo_admins])}\n---\n"
                f"**Admin Instructions:**\n"
                f"- Add the non-collaborators as collaborators to the "
                f"appropriate team(s) listed in "
                f"[teams](https://github.com/orgs/tianocore/teams)\n"
                f"- If they are no longer needed as reviewers, remove them "
                f"from [`Maintainers.txt`](https://github.com/tianocore/edk2/blob/HEAD/Maintainers.txt)",
            )

    # Add any new reviewers to the PR if needed.
    if new_pr_reviewers:
        print(
            f"::debug title=Adding New PR Reviewers::" f"{', '.join(new_pr_reviewers)}"
        )

        pr.create_review_request(reviewers=new_pr_reviewers)

    return new_pr_reviewers


def set_github_output(key: str, value: str):
    """Set a GitHub workflow output variable.

    This function writes to the GITHUB_OUTPUT file to set an output variable
    that can be used by subsequent steps in a GitHub workflow.

    Args:
        key (str): The output variable name.
        value (str): The output variable value.
    """
    github_output = os.environ.get('GITHUB_OUTPUT')
    if github_output:
        with open(github_output, 'a') as f:
            f.write(f"{key}={value}\n")


def set_github_env(key: str, value: str):
    """Set a GitHub workflow environment variable.

    This function writes to the GITHUB_ENV file to set an environment variable
    that will be available to subsequent steps in a GitHub workflow.

    Args:
        key (str): The environment variable name.
        value (str): The environment variable value.
    """
    github_env = os.environ.get('GITHUB_ENV')
    if github_env:
        with open(github_env, 'a') as f:
            f.write(f"{key}<<EOF\n{value}\nEOF\n")
