#!/usr/bin/env python3
#
# ======- github-automation - LLVM GitHub Automation Routines--*- python -*--==#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ==-------------------------------------------------------------------------==#

import argparse
from git import Repo  # type: ignore
import html
import json
import github
import os
import re
import requests
import sys
import textwrap
import time
from typing import List, Optional

beginner_comment = """
Hi!

This issue may be a good introductory issue for people new to working on LLVM. If you would like to work on this issue, your first steps are:

1. Check that no other contributor is working on this issue. If someone is assigned to the issue or claimed to be working on it, ping the person. After one week without a response, the assignee may be changed.
1. Leave a comment indicating that you are working on the issue, or just create a [pull request](https://github.com/llvm/llvm-project/pulls) after following the steps below. [Mention](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this issue in the description of the pull request.
1. Fix the issue locally. Be aware that [LLVM's AI policy](https://llvm.org/docs/AIToolPolicy.html#details) forbids the use of AI tools to fix good first issues since it squanders a learning opportunity. Using LLMs to search and learn is permitted, since the goal is learning.
1. [Run the test suite](https://llvm.org/docs/TestingGuide.html#unit-and-regression-tests) locally. Remember that the subdirectories under `test/` create fine-grained testing targets, so you can e.g. use `make check-clang-ast` to only run Clang's AST tests.
1. Create a Git commit.
1. Run [`git clang-format HEAD~1`](https://clang.llvm.org/docs/ClangFormat.html#git-integration) to format your changes.
1. Open a [pull request](https://github.com/llvm/llvm-project/pulls) to the [upstream repository](https://github.com/llvm/llvm-project) on GitHub. Detailed instructions can be found [in GitHub's documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). [Mention](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this issue in the description of the pull request.

If you have any further questions about this issue, don't hesitate to ask via a comment in the thread below.
"""


def _get_current_team(team_name, teams) -> Optional[github.Team.Team]:
    for team in teams:
        if team_name == team.name.lower():
            return team
    return None


def escape_description(str):
    # If the description of an issue/pull request is empty, the Github API
    # library returns None instead of an empty string. Handle this here to
    # avoid failures from trying to manipulate None.
    if str is None:
        return ""
    # https://github.com/github/markup/issues/1168#issuecomment-494946168
    str = html.escape(str, False)
    # '@' followed by alphanum is a user name
    str = re.sub(r"@(?=\w)", "@<!-- -->", str)
    # '#' followed by digits is considered an issue number
    str = re.sub(r"#(?=\d)", "#<!-- -->", str)
    return str


def format_author(user) -> str:
    # user.login is the account name, which everyone has. In theory it can be None,
    # perhaps for closed accounts. user.name is a longer display name for example
    # "First Last", which not everyone has set.
    author = "Author: "
    if user.name is not None:
        author += f"{user.name} ({user.login})"
    else:
        author += f"{user.login}"
    return author


class IssueSubscriber:
    @property
    def team_name(self) -> str:
        return self._team_name

    def __init__(self, token: str, repo: str, issue_number: int, label_name: str):
        self.repo = github.Github(auth=github.Auth.Token(token)).get_repo(repo)
        self.org = github.Github(auth=github.Auth.Token(token)).get_organization(
            self.repo.organization.login
        )
        self.issue = self.repo.get_issue(issue_number)
        self._team_name = "issue-subscribers-{}".format(label_name).lower()

    def run(self) -> bool:
        team = _get_current_team(self.team_name, self.org.get_teams())
        if not team:
            print(f"couldn't find team named {self.team_name}")
            return False

        comment = ""
        if team.slug == "issue-subscribers-good-first-issue":
            comment = "{}\n".format(beginner_comment)
            self.issue.create_comment(comment)

        body = escape_description(self.issue.body)
        comment = f"""
@llvm/{team.slug}

{format_author(self.issue.user)}

<details>
{body}
</details>
"""

        self.issue.create_comment(comment)
        return True


def human_readable_size(size, decimal_places=2):
    for unit in ["B", "KiB", "MiB", "GiB", "TiB", "PiB"]:
        if size < 1024.0 or unit == "PiB":
            break
        size /= 1024.0
    return f"{size:.{decimal_places}f} {unit}"


class PRSubscriber:
    @property
    def team_name(self) -> str:
        return self._team_name

    def __init__(self, token: str, repo: str, pr_number: int, label_name: str):
        self.repo = github.Github(auth=github.Auth.Token(token)).get_repo(repo)
        self.org = github.Github(auth=github.Auth.Token(token)).get_organization(
            self.repo.organization.login
        )
        self.pr = self.repo.get_issue(pr_number).as_pull_request()
        self._team_name = "pr-subscribers-{}".format(
            label_name.replace("+", "x")
        ).lower()
        self.COMMENT_TAG = "<!--LLVM PR SUMMARY COMMENT-->\n"

    def get_summary_comment(self) -> github.IssueComment.IssueComment:
        for comment in self.pr.as_issue().get_comments():
            if self.COMMENT_TAG in comment.body:
                return comment
        return None

    def run(self) -> bool:
        for label in self.pr.get_labels():
            # skip-precommit-approval label is intended for simple PR that don't
            # require approval. To reduce the volume of notifications, avoid
            # sending notifications to subscribers for PRs labeled as such.
            if label.name == "skip-precommit-approval":
                print(f"{label.name} label found, skip subscribers")
                return True

        patch = None
        team = _get_current_team(self.team_name, self.org.get_teams())
        if not team:
            print(f"couldn't find team named {self.team_name}")
            return False

        # GitHub limits comments to 65,536 characters, let's limit the diff
        # and the file list to 20kB each.
        STAT_LIMIT = 20 * 1024
        DIFF_LIMIT = 20 * 1024

        # Get statistics for each file
        diff_stats = f"{self.pr.changed_files} Files Affected:\n\n"
        for file in self.pr.get_files():
            diff_stats += f"- ({file.status}) {file.filename} ("
            if file.additions:
                diff_stats += f"+{file.additions}"
            if file.deletions:
                diff_stats += f"-{file.deletions}"
            diff_stats += ") "
            if file.status == "renamed":
                print(f"(from {file.previous_filename})")
            diff_stats += "\n"
            if len(diff_stats) > STAT_LIMIT:
                break

        # Get the diff
        try:
            patch = requests.get(self.pr.diff_url).text
        except:
            patch = ""

        patch_link = f"Full diff: {self.pr.diff_url}\n"
        if len(patch) > DIFF_LIMIT:
            patch_link = f"\nPatch is {human_readable_size(len(patch))}, truncated to {human_readable_size(DIFF_LIMIT)} below, full version: {self.pr.diff_url}\n"
            patch = patch[0:DIFF_LIMIT] + "...\n[truncated]\n"
        team_mention = "@llvm/{}".format(team.slug)

        body = escape_description(self.pr.body)
        # Note: the comment is in markdown and the code below
        # is sensible to line break
        comment = f"""
{self.COMMENT_TAG}
{team_mention}

{format_author(self.pr.user)}

<details>
<summary>Changes</summary>

{body}

---
{patch_link}

{diff_stats}

``````````diff
{patch}
``````````

</details>
"""

        summary_comment = self.get_summary_comment()
        if not summary_comment:
            self.pr.as_issue().create_comment(comment)
        elif team_mention + "\n" in summary_comment.body:
            print("Team {} already mentioned.".format(team.slug))
        else:
            summary_comment.edit(
                summary_comment.body.replace(
                    self.COMMENT_TAG, self.COMMENT_TAG + team_mention + "\n"
                )
            )
        return True

    def _get_current_team(self) -> Optional[github.Team.Team]:
        for team in self.org.get_teams():
            if self.team_name == team.name.lower():
                return team
        return None


def get_top_values(values: dict, top: int = 3) -> list:
    return [v for v in sorted(values.items(), key=lambda x: x[1], reverse=True)][:top]


def get_user_values_str(values: list) -> str:
    return ", ".join([f"@{v[0]} ({v[1]})" for v in values])


class PRGreeter:
    COMMENT_TAG = "<!--LLVM NEW CONTRIBUTOR COMMENT-->\n"

    def __init__(self, token: str, repo: str, pr_number: int):
        repo = github.Github(auth=github.Auth.Token(token)).get_repo(repo)
        self.pr = repo.get_issue(pr_number).as_pull_request()

    def run(self) -> bool:
        # We assume that this is only called for a PR that has just been opened
        # by a user new to LLVM and/or GitHub itself.

        # This text is using Markdown formatting.

        comment = f"""\
{PRGreeter.COMMENT_TAG}
Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/)."""
        self.pr.as_issue().create_comment(comment)
        return True


class CommitRequestGreeter:
    def __init__(self, token: str, repo: str, issue_number: int):
        self.repo = github.Github(auth=github.Auth.Token(token)).get_repo(repo)
        self.issue = self.repo.get_issue(issue_number)

    def run(self) -> bool:
        # Post greeter comment:
        comment = textwrap.dedent(
            f"""
            @{self.issue.user.login} thank you for applying for commit access.  Please  review the project's [code review policy](https://llvm.org/docs/CodeReview.html).
        """
        )
        self.issue.create_comment(comment)

        # Post activity summary:
        total_prs = 0
        merged_prs = 0
        merged_by = {}
        reviewed_by = {}
        for i in self.repo.get_issues(creator=self.issue.user.login, state="all"):
            print("Looking at issue:", i)
            issue_reviewed_by = set()
            try:
                pr = i.as_pull_request()
                total_prs += 1
                for c in pr.get_review_comments():
                    if c.user.login == self.issue.user.login:
                        continue
                    issue_reviewed_by.add(c.user.login)
                for r in issue_reviewed_by:
                    if r not in reviewed_by:
                        reviewed_by[r] = 1
                    else:
                        reviewed_by[r] += 1
                if pr.is_merged():
                    merged_prs += 1
                    merger = pr.merged_by.login
                    if merger not in merged_by:
                        merged_by[merger] = 1
                    else:
                        merged_by[merger] += 1
                    continue

            except github.GithubException as e:
                print(e)
                continue

        total_prs_url = f"https://github.com/llvm/llvm-project/pulls?q=author%3A{self.issue.user.login}+is%3Apr"
        merged_prs_url = total_prs_url + "+is%3Amerged"
        comment = f"""
            ### Activity Summary:
            * [{total_prs} Pull Requests]({total_prs_url})
            * [{merged_prs} Merged Pull Requests]({merged_prs_url})
            * Top 3 Committers: {get_user_values_str(get_top_values(merged_by))}
            * Top 3 Reviewers: {get_user_values_str(get_top_values(reviewed_by))}

            Reviewers should clearly state their reasoning for accepting or rejecting this request, and finish with a clear statement such as \"I approve of this request\", \"LGTM\", or \"I do not approve of this request\". Please review the instructions for [obtaining commit access](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access).
        """
        self.issue.create_comment(textwrap.dedent(comment))


class PRBuildbotInformation:
    COMMENT_TAG = "<!--LLVM BUILDBOT INFORMATION COMMENT-->\n"

    def __init__(self, token: str, repo: str, pr_number: int, author: str):
        repo = github.Github(auth=github.Auth.Token(token)).get_repo(repo)
        self.pr = repo.get_issue(pr_number).as_pull_request()
        self.author = author

    def should_comment(self) -> bool:
        # As soon as a new contributor has a PR merged, they are no longer a new contributor.
        # We can tell that they were a new contributor previously because we would have
        # added a new contributor greeting comment when they opened the PR.
        found_greeting = False
        for comment in self.pr.as_issue().get_comments():
            if PRGreeter.COMMENT_TAG in comment.body:
                found_greeting = True
            elif PRBuildbotInformation.COMMENT_TAG in comment.body:
                # When an issue is reopened, then closed as merged again, we should not
                # add a second comment. This event will be rare in practice as it seems
                # like it's only possible when the main branch is still at the exact
                # revision that the PR was merged on to, beyond that it's closed forever.
                return False
        return found_greeting

    def run(self) -> bool:
        if not self.should_comment():
            return

        # This text is using Markdown formatting. Some of the lines are longer
        # than others so that the final text is some reasonable looking paragraphs
        # after the long URLs are rendered.
        comment = f"""\
{PRBuildbotInformation.COMMENT_TAG}
@{self.author} Congratulations on having your first Pull Request (PR) merged into the LLVM Project!

Your changes will be combined with recent changes from other authors, then tested by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail [here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr).

If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of [LLVM development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy). You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are working as expected, well done!
"""
        self.pr.as_issue().create_comment(comment)
        return True


def setup_llvmbot_git(git_dir="."):
    """
    Configure the git repo in `git_dir` with the llvmbot account so
    commits are attributed to llvmbot.
    """
    repo = Repo(git_dir)
    with repo.config_writer() as config:
        config.set_value("user", "name", "llvmbot")
        config.set_value("user", "email", "llvmbot@llvm.org")


def extract_commit_hash(arg: str):
    """
    Extract the commit hash from the argument passed to /action github
    comment actions. We currently only support passing the commit hash
    directly or use the github URL, such as
    https://github.com/llvm/llvm-project/commit/2832d7941f4207f1fcf813b27cf08cecc3086959
    """
    github_prefix = "https://github.com/llvm/llvm-project/commit/"
    if arg.startswith(github_prefix):
        return arg[len(github_prefix) :]
    return arg


class ReleaseWorkflow:
    CHERRY_PICK_FAILED_LABEL = "release:cherry-pick-failed"

    """
    This class implements the sub-commands for the release-workflow command.
    The current sub-commands are:
        * create-branch
        * create-pull-request

    The execute_command method will automatically choose the correct sub-command
    based on the text in stdin.
    """

    def __init__(
        self,
        token: str,
        repo: str,
        issue_number: int,
        branch_repo_name: str,
        branch_repo_token: str,
        llvm_project_dir: str,
        requested_by: str,
    ) -> None:
        self._token = token
        self._repo_name = repo
        self._issue_number = issue_number
        self._branch_repo_name = branch_repo_name
        if branch_repo_token:
            self._branch_repo_token = branch_repo_token
        else:
            self._branch_repo_token = self.token
        self._llvm_project_dir = llvm_project_dir
        self._requested_by = requested_by

    @property
    def token(self) -> str:
        return self._token

    @property
    def repo_name(self) -> str:
        return self._repo_name

    @property
    def issue_number(self) -> int:
        return self._issue_number

    @property
    def branch_repo_owner(self) -> str:
        return self.branch_repo_name.split("/")[0]

    @property
    def branch_repo_name(self) -> str:
        return self._branch_repo_name

    @property
    def branch_repo_token(self) -> str:
        return self._branch_repo_token

    @property
    def llvm_project_dir(self) -> str:
        return self._llvm_project_dir

    @property
    def requested_by(self) -> str:
        return self._requested_by

    @property
    def repo(self) -> github.Repository.Repository:
        return github.Github(auth=github.Auth.Token(self.token)).get_repo(
            self.repo_name
        )

    @property
    def issue(self) -> github.Issue.Issue:
        return self.repo.get_issue(self.issue_number)

    @property
    def push_url(self) -> str:
        return "https://{}@github.com/{}".format(
            self.branch_repo_token, self.branch_repo_name
        )

    @property
    def branch_name(self) -> str:
        return "issue{}".format(self.issue_number)

    @property
    def release_branch_for_issue(self) -> Optional[str]:
        issue = self.issue
        milestone = issue.milestone
        if milestone is None:
            return None
        m = re.search("branch: (.+)", milestone.description)
        if m:
            return m.group(1)
        return None

    def update_issue_project_status(self) -> None:
        """
        A common workflow is to merge a PR and then use the /cherry-pick
        command in a pull request comment to backport the change to the
        release branch.  In this case, once the new PR for the backport has
        been created, we want to mark the project status for the original PR
        as Done.  This is becuase we can track progress now on the new PR
        which is targeting the release branch.

        """

        pr = self.issue.as_pull_request()
        if not pr:
            return

        if pr.state != "closed":
            return

        gh = github.Github(auth=github.Auth.Token(self.token))
        query = """
            query($node_id: ID!) {
              node(id: $node_id) {
                ... on PullRequest {
                  url
                  projectItems(first:100){
                    nodes {
                      id
                      project {
                        id
                        number
                        field(name: "Status") {
                          ... on ProjectV2SingleSelectField {
                            id
                            name
                            options {
                              id
                              name
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
        """
        variables = {"node_id": pr.node_id}
        res_header, res_data = gh._Github__requester.graphql_query(
            query=query, variables=variables
        )
        print(res_header)

        llvm_release_status_project_number = 3
        for item in res_data["data"]["node"]["projectItems"]["nodes"]:
            project = item["project"]
            if project["number"] != llvm_release_status_project_number:
                continue
            status_field = project["field"]
            for option in status_field["options"]:
                if option["name"] != "Done":
                    continue
                variables = {
                    "project": project["id"],
                    "item": item["id"],
                    "status_field": status_field["id"],
                    "status_value": option["id"],
                }

                query = """
                  mutation($project: ID!, $item: ID!, $status_field: ID!, $status_value: String!) {
                    set_status:
                    updateProjectV2ItemFieldValue(input: {
                      projectId: $project
                      itemId: $item
                      fieldId: $status_field
                      value: {
                        singleSelectOptionId: $status_value
                      }
                    }) {
                      projectV2Item {
                        id
                      }
                    }
                  }
                """

                res_header, res_data = gh._Github__requester.graphql_query(
                    query=query, variables=variables
                )
                print(res_header)

    def print_release_branch(self) -> None:
        print(self.release_branch_for_issue)

    def issue_notify_branch(self) -> None:
        self.issue.create_comment(
            "/branch {}/{}".format(self.branch_repo_name, self.branch_name)
        )

    def issue_notify_pull_request(self, pull: github.PullRequest.PullRequest) -> None:
        self.issue.create_comment(
            "/pull-request {}#{}".format(self.repo_name, pull.number)
        )

    def make_ignore_comment(self, comment: str) -> str:
        """
        Returns the comment string with a prefix that will cause
        a Github workflow to skip parsing this comment.

        :param str comment: The comment to ignore
        """
        return "<!--IGNORE-->\n" + comment

    def issue_notify_no_milestone(self, comment: List[str]) -> None:
        message = "{}\n\nError: Command failed due to missing milestone.".format(
            "".join([">" + line for line in comment])
        )
        self.issue.create_comment(self.make_ignore_comment(message))

    @property
    def action_url(self) -> str:
        if os.getenv("CI"):
            return "https://github.com/{}/actions/runs/{}".format(
                os.getenv("GITHUB_REPOSITORY"), os.getenv("GITHUB_RUN_ID")
            )
        return ""

    def issue_notify_cherry_pick_failure(
        self, commit: str
    ) -> github.IssueComment.IssueComment:
        message = self.make_ignore_comment(
            "Failed to cherry-pick: {}\n\n".format(commit)
        )
        action_url = self.action_url
        if action_url:
            message += action_url + "\n\n"
        message += "Please manually backport the fix and push it to your github fork.  Once this is done, please create a [pull request](https://github.com/llvm/llvm-project/compare)"
        issue = self.issue
        comment = issue.create_comment(message)
        issue.add_to_labels(self.CHERRY_PICK_FAILED_LABEL)
        return comment

    def issue_notify_pull_request_failure(
        self, branch: str
    ) -> github.IssueComment.IssueComment:
        message = "Failed to create pull request for {} ".format(branch)
        message += self.action_url
        return self.issue.create_comment(message)

    def issue_remove_cherry_pick_failed_label(self):
        if self.CHERRY_PICK_FAILED_LABEL in [l.name for l in self.issue.labels]:
            self.issue.remove_from_labels(self.CHERRY_PICK_FAILED_LABEL)

    def get_main_commit(self, cherry_pick_sha: str) -> github.Commit.Commit:
        commit = self.repo.get_commit(cherry_pick_sha)
        message = commit.commit.message
        m = re.search(r"\(cherry picked from commit ([0-9a-f]+)\)", message)
        if not m:
            return None
        return self.repo.get_commit(m.group(1))

    def pr_request_review(self, pr: github.PullRequest.PullRequest):
        """
        This function will try to find the best reviewers for `commits` and
        then add a comment requesting review of the backport and add them as
        reviewers.

        The reviewers selected are those users who approved the pull request
        for the main branch.
        """
        reviewers = []
        for commit in pr.get_commits():
            main_commit = self.get_main_commit(commit.sha)
            if not main_commit:
                continue
            for pull in main_commit.get_pulls():
                for review in pull.get_reviews():
                    if review.state != "APPROVED":
                        continue
                    # Ensure the reviewer list contains only unique entries, as
                    # reviewers may have submitted more than one round of review.
                    if review.user.login not in reviewers:
                        reviewers.append(review.user.login)
        if len(reviewers):
            message = "{} What do you think about merging this PR to the release branch?".format(
                " ".join(["@" + r for r in reviewers])
            )
            pr.create_issue_comment(message)
            pr.create_review_request(reviewers)

    def create_branch(self, commits: List[str]) -> bool:
        """
        This function attempts to backport `commits` into the branch associated
        with `self.issue_number`.

        If this is successful, then the branch is pushed to `self.branch_repo_name`, if not,
        a comment is added to the issue saying that the cherry-pick failed.

        :param list commits: List of commits to cherry-pick.

        """
        print("cherry-picking", commits)
        branch_name = self.branch_name
        local_repo = Repo(self.llvm_project_dir)
        local_repo.git.checkout(self.release_branch_for_issue)

        for c in commits:
            try:
                local_repo.git.cherry_pick("-x", c)
            except Exception as e:
                self.issue_notify_cherry_pick_failure(c)
                raise e

        push_url = self.push_url
        print("Pushing to {} {}".format(push_url, branch_name))
        local_repo.git.push(push_url, "HEAD:{}".format(branch_name), force=True)

        self.issue_remove_cherry_pick_failed_label()
        return self.create_pull_request(
            self.branch_repo_owner, self.repo_name, branch_name, commits
        )

    def check_if_pull_request_exists(
        self, repo: github.Repository.Repository, head: str
    ) -> bool:
        pulls = repo.get_pulls(head=head)
        return pulls.totalCount != 0

    def create_pull_request(
        self, owner: str, repo_name: str, branch: str, commits: List[str]
    ) -> bool:
        """
        Create a pull request in `self.repo_name`.  The base branch of the
        pull request will be chosen based on the the milestone attached to
        the issue represented by `self.issue_number`  For example if the milestone
        is Release 13.0.1, then the base branch will be release/13.x. `branch`
        will be used as the compare branch.
        https://docs.github.com/en/get-started/quickstart/github-glossary#base-branch
        https://docs.github.com/en/get-started/quickstart/github-glossary#compare-branch
        """
        repo = github.Github(auth=github.Auth.Token(self.token)).get_repo(
            self.repo_name
        )
        issue_ref = "{}#{}".format(self.repo_name, self.issue_number)
        pull = None
        release_branch_for_issue = self.release_branch_for_issue
        if release_branch_for_issue is None:
            return False

        head = f"{owner}:{branch}"
        if self.check_if_pull_request_exists(repo, head):
            print("PR already exists...")
            return True
        try:
            commit_message = repo.get_commit(commits[-1]).commit.message
            message_lines = commit_message.splitlines()
            title = "{}: {}".format(release_branch_for_issue, message_lines[0])
            body = "Backport {}\n\nRequested by: @{}".format(
                " ".join(commits), self.requested_by
            )
            pull = repo.create_pull(
                title=title,
                body=body,
                base=release_branch_for_issue,
                head=head,
                maintainer_can_modify=True,
            )

            pull.as_issue().edit(milestone=self.issue.milestone)

            # Once the pull request has been created, we can close the
            # issue that was used to request the cherry-pick
            self.issue.edit(state="closed", state_reason="completed")

            try:
                self.pr_request_review(pull)
            except Exception as e:
                print("error: Failed while searching for reviewers", e)

        except Exception as e:
            self.issue_notify_pull_request_failure(branch)
            raise e

        if pull is None:
            return False

        self.issue_notify_pull_request(pull)
        self.issue_remove_cherry_pick_failed_label()
        self.update_issue_project_status()

        # TODO(tstellar): Do you really want to always return True?
        return True

    def execute_command(self) -> bool:
        """
        This function reads lines from STDIN and executes the first command
        that it finds.  The supported command is:
        /cherry-pick< ><:> commit0 <commit1> <commit2> <...>
        """
        for line in sys.stdin:
            line.rstrip()
            m = re.search(r"/cherry-pick\s*:? *(.*)", line)
            if not m:
                continue

            args = m.group(1)

            arg_list = args.split()
            commits = list(map(lambda a: extract_commit_hash(a), arg_list))
            return self.create_branch(commits)

        print("Do not understand input:")
        print(sys.stdin.readlines())
        return False


def request_release_note(token: str, repo_name: str, pr_number: int):
    repo = github.Github(auth=github.Auth.Token(token)).get_repo(repo_name)
    pr = repo.get_issue(pr_number).as_pull_request()
    submitter = pr.user.login
    if submitter == "llvmbot":
        m = re.search("Requested by: @(.+)$", pr.body)
        if not m:
            submitter = None
            print("Warning could not determine user who requested backport.")
        submitter = m.group(1)

    mention = ""
    if submitter:
        mention = f"@{submitter}"

    comment = f"{mention} (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix.  When you are done, please add the release:note label to this PR. "
    try:
        pr.as_issue().create_comment(comment)
    except:
        # Failed to create comment so emit file instead
        with open("comments", "w") as file:
            data = [{"body": comment}]
            json.dump(data, file)


parser = argparse.ArgumentParser()
parser.add_argument(
    "--token", type=str, required=True, help="GitHub authentication token"
)
parser.add_argument(
    "--repo",
    type=str,
    default=os.getenv("GITHUB_REPOSITORY", "llvm/llvm-project"),
    help="The GitHub repository that we are working with in the form of <owner>/<repo> (e.g. llvm/llvm-project)",
)
subparsers = parser.add_subparsers(dest="command")

issue_subscriber_parser = subparsers.add_parser("issue-subscriber")
issue_subscriber_parser.add_argument("--label-name", type=str, required=True)
issue_subscriber_parser.add_argument("--issue-number", type=int, required=True)

pr_subscriber_parser = subparsers.add_parser("pr-subscriber")
pr_subscriber_parser.add_argument("--label-name", type=str, required=True)
pr_subscriber_parser.add_argument("--issue-number", type=int, required=True)

pr_greeter_parser = subparsers.add_parser("pr-greeter")
pr_greeter_parser.add_argument("--issue-number", type=int, required=True)

commit_request_greeter = subparsers.add_parser("commit-request-greeter")
commit_request_greeter.add_argument("--issue-number", type=int, required=True)

pr_buildbot_information_parser = subparsers.add_parser("pr-buildbot-information")
pr_buildbot_information_parser.add_argument("--issue-number", type=int, required=True)
pr_buildbot_information_parser.add_argument("--author", type=str, required=True)

release_workflow_parser = subparsers.add_parser("release-workflow")
release_workflow_parser.add_argument(
    "--llvm-project-dir",
    type=str,
    default=".",
    help="directory containing the llvm-project checkout",
)
release_workflow_parser.add_argument(
    "--issue-number", type=int, required=True, help="The issue number to update"
)
release_workflow_parser.add_argument(
    "--branch-repo-token",
    type=str,
    help="GitHub authentication token to use for the repository where new branches will be pushed. Defaults to TOKEN.",
)
release_workflow_parser.add_argument(
    "--branch-repo",
    type=str,
    default="llvmbot/llvm-project",
    help="The name of the repo where new branches will be pushed (e.g. llvm/llvm-project)",
)
release_workflow_parser.add_argument(
    "sub_command",
    type=str,
    choices=["print-release-branch", "auto"],
    help="Print to stdout the name of the release branch ISSUE_NUMBER should be backported to",
)

llvmbot_git_config_parser = subparsers.add_parser(
    "setup-llvmbot-git",
    help="Set the default user and email for the git repo in LLVM_PROJECT_DIR to llvmbot",
)
release_workflow_parser.add_argument(
    "--requested-by",
    type=str,
    required=True,
    help="The user that requested this backport",
)

request_release_note_parser = subparsers.add_parser(
    "request-release-note",
    help="Request a release note for a pull request",
)
request_release_note_parser.add_argument(
    "--pr-number",
    type=int,
    required=True,
    help="The pull request to request the release note",
)


args = parser.parse_args()

if args.command == "issue-subscriber":
    issue_subscriber = IssueSubscriber(
        args.token, args.repo, args.issue_number, args.label_name
    )
    issue_subscriber.run()
elif args.command == "pr-subscriber":
    pr_subscriber = PRSubscriber(
        args.token, args.repo, args.issue_number, args.label_name
    )
    pr_subscriber.run()
elif args.command == "pr-greeter":
    pr_greeter = PRGreeter(args.token, args.repo, args.issue_number)
    pr_greeter.run()
elif args.command == "commit-request-greeter":
    commit_greeter = CommitRequestGreeter(args.token, args.repo, args.issue_number)
    commit_greeter.run()
elif args.command == "pr-buildbot-information":
    pr_buildbot_information = PRBuildbotInformation(
        args.token, args.repo, args.issue_number, args.author
    )
    pr_buildbot_information.run()
elif args.command == "release-workflow":
    release_workflow = ReleaseWorkflow(
        args.token,
        args.repo,
        args.issue_number,
        args.branch_repo,
        args.branch_repo_token,
        args.llvm_project_dir,
        args.requested_by,
    )
    if not release_workflow.release_branch_for_issue:
        release_workflow.issue_notify_no_milestone(sys.stdin.readlines())
        sys.exit(1)
    if args.sub_command == "print-release-branch":
        release_workflow.print_release_branch()
    else:
        if not release_workflow.execute_command():
            sys.exit(1)
elif args.command == "setup-llvmbot-git":
    setup_llvmbot_git()
elif args.command == "request-release-note":
    request_release_note(args.token, args.repo, args.pr_number)
