# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import copy
import functools
import optparse
import re
import sys
from typing import List

from command import DEFAULT_LOCAL_JOBS
from command import InteractiveCommand
from editor import Editor
from error import GitError
from error import SilentRepoExitError
from error import UploadError
from git_command import GitCommand
from git_refs import R_HEADS
import git_superproject
from hooks import RepoHook
from project import ReviewableBranch
from repo_logging import RepoLogger
from subcmds.sync import LocalSyncState


_DEFAULT_UNUSUAL_COMMIT_THRESHOLD = 5
logger = RepoLogger(__file__)


class UploadExitError(SilentRepoExitError):
    """Indicates that there is an upload command error requiring a sys exit."""


def _VerifyPendingCommits(branches: List[ReviewableBranch]) -> bool:
    """Perform basic safety checks on the given set of branches.

    Ensures that each branch does not have a "large" number of commits
    and, if so, prompts the user to confirm they want to proceed with
    the upload.

    Returns true if all branches pass the safety check or the user
    confirmed. Returns false if the upload should be aborted.
    """

    # Determine if any branch has a suspicious number of commits.
    many_commits = False
    for branch in branches:
        # Get the user's unusual threshold for the branch.
        #
        # Each branch may be configured to have a different threshold.
        remote = branch.project.GetBranch(branch.name).remote
        key = f"review.{remote.review}.uploadwarningthreshold"
        threshold = branch.project.config.GetInt(key)
        if threshold is None:
            threshold = _DEFAULT_UNUSUAL_COMMIT_THRESHOLD

        # If the branch has more commits than the threshold, show a warning.
        if len(branch.commits) > threshold:
            many_commits = True
            break

    # If any branch has many commits, prompt the user.
    if many_commits:
        if len(branches) > 1:
            logger.warning(
                "ATTENTION: One or more branches has an unusually high number "
                "of commits."
            )
        else:
            logger.warning(
                "ATTENTION: You are uploading an unusually high number of "
                "commits."
            )
        logger.warning(
            "YOU PROBABLY DO NOT MEAN TO DO THIS. (Did you rebase across "
            "branches?)"
        )
        answer = input(
            "If you are sure you intend to do this, type 'yes': "
        ).strip()
        return answer == "yes"

    return True


def _die(fmt, *args):
    msg = fmt % args
    logger.error("error: %s", msg)
    raise UploadExitError(msg)


def _SplitEmails(values):
    result = []
    for value in values:
        result.extend([s.strip() for s in value.split(",")])
    return result


class Upload(InteractiveCommand):
    COMMON = True
    helpSummary = "Upload changes for code review"
    helpUsage = """
%prog [--re --cc] [<project>]...
"""
    helpDescription = """
The '%prog' command is used to send changes to the Gerrit Code
Review system.  It searches for topic branches in local projects
that have not yet been published for review.  If multiple topic
branches are found, '%prog' opens an editor to allow the user to
select which branches to upload.

'%prog' searches for uploadable changes in all projects listed at
the command line.  Projects can be specified either by name, or by
a relative or absolute path to the project's local directory. If no
projects are specified, '%prog' will search for uploadable changes
in all projects listed in the manifest.

If the --reviewers or --cc options are passed, those emails are
added to the respective list of users, and emails are sent to any
new users.  Users passed as --reviewers must already be registered
with the code review system, or the upload will fail.

While most normal Gerrit options have dedicated command line options,
direct access to the Gerit options is available via --push-options.
This is useful when Gerrit has newer functionality that %prog doesn't
yet support, or doesn't have plans to support.  See the Push Options
documentation for more details:
https://gerrit-review.googlesource.com/Documentation/user-upload.html#push_options

# Configuration

review.URL.autoupload:

To disable the "Upload ... (y/N)?" prompt, you can set a per-project
or global Git configuration option.  If review.URL.autoupload is set
to "true" then repo will assume you always answer "y" at the prompt,
and will not prompt you further.  If it is set to "false" then repo
will assume you always answer "n", and will abort.

review.URL.autoreviewer:

To automatically append a user or mailing list to reviews, you can set
a per-project or global Git option to do so.

review.URL.autocopy:

To automatically copy a user or mailing list to all uploaded reviews,
you can set a per-project or global Git option to do so. Specifically,
review.URL.autocopy can be set to a comma separated list of reviewers
who you always want copied on all uploads with a non-empty --re
argument.

review.URL.username:

Override the username used to connect to Gerrit Code Review.
By default the local part of the email address is used.

The URL must match the review URL listed in the manifest XML file,
or in the .git/config within the project.  For example:

  [remote "origin"]
    url = git://git.example.com/project.git
    review = http://review.example.com/

  [review "http://review.example.com/"]
    autoupload = true
    autocopy = johndoe@company.com,my-team-alias@company.com

review.URL.uploadtopic:

To add a topic branch whenever uploading a commit, you can set a
per-project or global Git option to do so. If review.URL.uploadtopic
is set to "true" then repo will assume you always want the equivalent
of the -t option to the repo command. If unset or set to "false" then
repo will make use of only the command line option.

review.URL.uploadhashtags:

To add hashtags whenever uploading a commit, you can set a per-project
or global Git option to do so. The value of review.URL.uploadhashtags
will be used as comma delimited hashtags like the --hashtag option.

review.URL.uploadlabels:

To add labels whenever uploading a commit, you can set a per-project
or global Git option to do so. The value of review.URL.uploadlabels
will be used as comma delimited labels like the --label option.

review.URL.uploadnotify:

Control e-mail notifications when uploading.
https://gerrit-review.googlesource.com/Documentation/user-upload.html#notify

review.URL.uploadwarningthreshold:

Repo will warn you if you are attempting to upload a large number
of commits in one or more branches. By default, the threshold
is five commits. This option allows you to override the warning
threshold to a different value.

# References

Gerrit Code Review:  https://www.gerritcodereview.com/

"""
    PARALLEL_JOBS = DEFAULT_LOCAL_JOBS

    def _Options(self, p):
        p.add_option(
            "-t",
            "--topic-branch",
            dest="auto_topic",
            action="store_true",
            help="set the topic to the local branch name",
        )
        p.add_option(
            "--topic",
            help="set topic for the change",
        )
        p.add_option(
            "--hashtag",
            "--ht",
            dest="hashtags",
            action="append",
            default=[],
            help="add hashtags (comma delimited) to the review",
        )
        p.add_option(
            "--hashtag-branch",
            "--htb",
            action="store_true",
            help="add local branch name as a hashtag",
        )
        p.add_option(
            "-l",
            "--label",
            dest="labels",
            action="append",
            default=[],
            help="add a label when uploading",
        )
        p.add_option(
            "--pd",
            "--patchset-description",
            dest="patchset_description",
            help="description for patchset",
        )
        p.add_option(
            "--re",
            "--reviewers",
            type="string",
            action="append",
            dest="reviewers",
            help="request reviews from these people",
        )
        p.add_option(
            "--cc",
            type="string",
            action="append",
            help="also send email to these email addresses",
        )
        p.add_option(
            "--br",
            "--branch",
            type="string",
            action="store",
            dest="branch",
            help="(local) branch to upload",
        )
        p.add_option(
            "-c",
            "--current-branch",
            action="store_true",
            help="upload current git branch",
        )
        p.add_option(
            "--no-current-branch",
            dest="current_branch",
            action="store_false",
            help="upload all git branches",
        )
        # Turn this into a warning & remove this someday.
        p.add_option(
            "--cbr",
            dest="current_branch",
            action="store_true",
            help=optparse.SUPPRESS_HELP,
        )
        p.add_option(
            "--ne",
            "--no-emails",
            action="store_false",
            dest="notify",
            default=True,
            help="do not send e-mails on upload",
        )
        p.add_option(
            "-p",
            "--private",
            action="store_true",
            default=False,
            help="upload as a private change (deprecated; use --wip)",
        )
        p.add_option(
            "-w",
            "--wip",
            action="store_true",
            default=False,
            help="upload as a work-in-progress change",
        )
        p.add_option(
            "-r",
            "--ready",
            action="store_true",
            default=False,
            help="mark change as ready (clears work-in-progress setting)",
        )
        p.add_option(
            "-o",
            "--push-option",
            type="string",
            action="append",
            dest="push_options",
            default=[],
            help="additional push options to transmit",
        )
        p.add_option(
            "-D",
            "--destination",
            "--dest",
            type="string",
            action="store",
            dest="dest_branch",
            metavar="BRANCH",
            help="submit for review on this target branch",
        )
        p.add_option(
            "-n",
            "--dry-run",
            dest="dryrun",
            default=False,
            action="store_true",
            help="do everything except actually upload the CL",
        )
        p.add_option(
            "-y",
            "--yes",
            default=False,
            action="store_true",
            help="answer yes to all safe prompts",
        )
        p.add_option(
            "--ignore-untracked-files",
            action="store_true",
            default=False,
            help="ignore untracked files in the working copy",
        )
        p.add_option(
            "--no-ignore-untracked-files",
            dest="ignore_untracked_files",
            action="store_false",
            help="always ask about untracked files in the working copy",
        )
        p.add_option(
            "--no-cert-checks",
            dest="validate_certs",
            action="store_false",
            default=True,
            help="disable verifying ssl certs (unsafe)",
        )
        RepoHook.AddOptionGroup(p, "pre-upload")

    def _SingleBranch(self, opt, branch, people):
        project = branch.project
        name = branch.name
        remote = project.GetBranch(name).remote

        key = "review.%s.autoupload" % remote.review
        answer = project.config.GetBoolean(key)

        if answer is False:
            _die("upload blocked by %s = false" % key)

        if answer is None:
            date = branch.date
            commit_list = branch.commits

            destination = (
                opt.dest_branch or project.dest_branch or project.revisionExpr
            )
            print(
                "Upload project %s/ to remote branch %s%s:"
                % (
                    project.RelPath(local=opt.this_manifest_only),
                    destination,
                    " (private)" if opt.private else "",
                )
            )
            print(
                "  branch %s (%2d commit%s, %s):"
                % (
                    name,
                    len(commit_list),
                    len(commit_list) != 1 and "s" or "",
                    date,
                )
            )
            for commit in commit_list:
                print("         %s" % commit)

            print("to %s (y/N)? " % remote.review, end="", flush=True)
            if opt.yes:
                print("<--yes>")
                answer = True
            else:
                answer = sys.stdin.readline().strip().lower()
                answer = answer in ("y", "yes", "1", "true", "t")
            if not answer:
                _die("upload aborted by user")

        # Perform some basic safety checks prior to uploading.
        if not opt.yes and not _VerifyPendingCommits([branch]):
            _die("upload aborted by user")

        self._UploadAndReport(opt, [branch], people)

    def _MultipleBranches(self, opt, pending, people):
        projects = {}
        branches = {}

        script = []
        script.append("# Uncomment the branches to upload:")
        for project, avail in pending:
            project_path = project.RelPath(local=opt.this_manifest_only)
            script.append("#")
            script.append(f"# project {project_path}/:")

            b = {}
            for branch in avail:
                if branch is None:
                    continue
                name = branch.name
                date = branch.date
                commit_list = branch.commits

                if b:
                    script.append("#")
                destination = (
                    opt.dest_branch
                    or project.dest_branch
                    or project.revisionExpr
                )
                script.append(
                    "#  branch %s (%2d commit%s, %s) to remote branch %s:"
                    % (
                        name,
                        len(commit_list),
                        len(commit_list) != 1 and "s" or "",
                        date,
                        destination,
                    )
                )
                for commit in commit_list:
                    script.append("#         %s" % commit)
                b[name] = branch

            projects[project_path] = project
            branches[project_path] = b
        script.append("")

        script = Editor.EditString("\n".join(script)).split("\n")

        project_re = re.compile(r"^#?\s*project\s*([^\s]+)/:$")
        branch_re = re.compile(r"^\s*branch\s*([^\s(]+)\s*\(.*")

        project = None
        todo = []

        for line in script:
            m = project_re.match(line)
            if m:
                name = m.group(1)
                project = projects.get(name)
                if not project:
                    _die("project %s not available for upload", name)
                continue

            m = branch_re.match(line)
            if m:
                name = m.group(1)
                if not project:
                    _die("project for branch %s not in script", name)
                project_path = project.RelPath(local=opt.this_manifest_only)
                branch = branches[project_path].get(name)
                if not branch:
                    _die("branch %s not in %s", name, project_path)
                todo.append(branch)
        if not todo:
            _die("nothing uncommented for upload")

        # Perform some basic safety checks prior to uploading.
        if not opt.yes and not _VerifyPendingCommits(todo):
            _die("upload aborted by user")

        self._UploadAndReport(opt, todo, people)

    def _AppendAutoList(self, branch, people):
        """
        Appends the list of reviewers in the git project's config.
        Appends the list of users in the CC list in the git project's config if
        a non-empty reviewer list was found.
        """
        name = branch.name
        project = branch.project

        key = "review.%s.autoreviewer" % project.GetBranch(name).remote.review
        raw_list = project.config.GetString(key)
        if raw_list is not None:
            people[0].extend([entry.strip() for entry in raw_list.split(",")])

        key = "review.%s.autocopy" % project.GetBranch(name).remote.review
        raw_list = project.config.GetString(key)
        if raw_list is not None and len(people[0]) > 0:
            people[1].extend([entry.strip() for entry in raw_list.split(",")])

    def _FindGerritChange(self, branch):
        last_pub = branch.project.WasPublished(branch.name)
        if last_pub is None:
            return ""

        refs = branch.GetPublishedRefs()
        try:
            # refs/changes/XYZ/N --> XYZ
            return refs.get(last_pub).split("/")[-2]
        except (AttributeError, IndexError):
            return ""

    def _UploadBranch(self, opt, branch, original_people):
        """Upload Branch."""
        people = copy.deepcopy(original_people)
        self._AppendAutoList(branch, people)

        # Check if topic branches should be sent to the server during
        # upload.
        if opt.topic is None:
            if opt.auto_topic is not True:
                key = "review.%s.uploadtopic" % branch.project.remote.review
                opt.auto_topic = branch.project.config.GetBoolean(key)
            if opt.auto_topic:
                opt.topic = branch.name

        def _ExpandCommaList(value):
            """Split |value| up into comma delimited entries."""
            if not value:
                return
            for ret in value.split(","):
                ret = ret.strip()
                if ret:
                    yield ret

        # Check if hashtags should be included.
        key = "review.%s.uploadhashtags" % branch.project.remote.review
        hashtags = set(_ExpandCommaList(branch.project.config.GetString(key)))
        for tag in opt.hashtags:
            hashtags.update(_ExpandCommaList(tag))
        if opt.hashtag_branch:
            hashtags.add(branch.name)

        # Check if labels should be included.
        key = "review.%s.uploadlabels" % branch.project.remote.review
        labels = set(_ExpandCommaList(branch.project.config.GetString(key)))
        for label in opt.labels:
            labels.update(_ExpandCommaList(label))

        # Handle e-mail notifications.
        if opt.notify is False:
            notify = "NONE"
        else:
            key = "review.%s.uploadnotify" % branch.project.remote.review
            notify = branch.project.config.GetString(key)

        destination = opt.dest_branch or branch.project.dest_branch

        if branch.project.dest_branch and not opt.dest_branch:
            merge_branch = self._GetMergeBranch(
                branch.project, local_branch=branch.name
            )

            full_dest = destination
            if not full_dest.startswith(R_HEADS):
                full_dest = R_HEADS + full_dest
            full_revision = branch.project.revisionExpr
            if not full_revision.startswith(R_HEADS):
                full_revision = R_HEADS + full_revision

            # If the merge branch of the local branch is different from
            # the project's revision AND destination, this might not be
            # intentional.
            if (
                merge_branch
                and merge_branch != full_revision
                and merge_branch != full_dest
            ):
                print(
                    f"For local branch {branch.name}: merge branch "
                    f"{merge_branch} does not match destination branch "
                    f"{destination} and revision {branch.project.revisionExpr}"
                )
                print("skipping upload.")
                print(
                    f"Please use `--destination {destination}` if this "
                    "is intentional"
                )
                branch.uploaded = False
                return

        # If using superproject, add the root repo as a push option.
        manifest = branch.project.manifest
        push_options = list(opt.push_options)
        if git_superproject.UseSuperproject(None, manifest):
            sp = manifest.superproject
            if sp:
                r_id = sp.repo_id
                if r_id:
                    push_options.append(f"custom-keyed-value=rootRepo:{r_id}")

        branch.UploadForReview(
            people,
            dryrun=opt.dryrun,
            topic=opt.topic,
            hashtags=hashtags,
            labels=labels,
            private=opt.private,
            notify=notify,
            wip=opt.wip,
            ready=opt.ready,
            dest_branch=destination,
            validate_certs=opt.validate_certs,
            push_options=push_options,
            patchset_description=opt.patchset_description,
        )

        branch.uploaded = True

    def _UploadAndReport(self, opt, todo, people):
        have_errors = False
        aggregate_errors = []
        for branch in todo:
            try:
                self._UploadBranch(opt, branch, people)
            except (UploadError, GitError) as e:
                self.git_event_log.ErrorEvent(f"upload error: {e}")
                branch.error = e
                aggregate_errors.append(e)
                branch.uploaded = False
                have_errors = True

        print(file=sys.stderr)
        print("-" * 70, file=sys.stderr)

        if have_errors:
            for branch in todo:
                if not branch.uploaded:
                    if len(str(branch.error)) <= 30:
                        fmt = " (%s)"
                    else:
                        fmt = "\n       (%s)"
                    print(
                        ("[FAILED] %-15s %-15s" + fmt)
                        % (
                            branch.project.RelPath(local=opt.this_manifest_only)
                            + "/",
                            branch.name,
                            str(branch.error),
                        ),
                        file=sys.stderr,
                    )
            print()

        for branch in todo:
            if branch.uploaded:
                print(
                    "[OK    ] %-15s %s"
                    % (
                        branch.project.RelPath(local=opt.this_manifest_only)
                        + "/",
                        branch.name,
                    ),
                    file=sys.stderr,
                )

        if have_errors:
            raise UploadExitError(aggregate_errors=aggregate_errors)

    def _GetMergeBranch(self, project, local_branch=None):
        if local_branch is None:
            p = GitCommand(
                project,
                ["rev-parse", "--abbrev-ref", "HEAD"],
                capture_stdout=True,
                capture_stderr=True,
            )
            p.Wait()
            local_branch = p.stdout.strip()
        p = GitCommand(
            project,
            ["config", "--get", "branch.%s.merge" % local_branch],
            capture_stdout=True,
            capture_stderr=True,
        )
        p.Wait()
        merge_branch = p.stdout.strip()
        return merge_branch

    @classmethod
    def _GatherOne(cls, opt, project_idx):
        """Figure out the upload status for |project|."""
        project = cls.get_parallel_context()["projects"][project_idx]
        if opt.current_branch:
            cbr = project.CurrentBranch
            up_branch = project.GetUploadableBranch(cbr)
            avail = [up_branch] if up_branch else None
        else:
            avail = project.GetUploadableBranches(opt.branch)
        return (project_idx, avail)

    def Execute(self, opt, args):
        projects = self.GetProjects(
            args, all_manifests=not opt.this_manifest_only
        )

        def _ProcessResults(_pool, _out, results):
            pending = []
            for result in results:
                project_idx, avail = result
                project = projects[project_idx]
                if avail is None:
                    logger.error(
                        'repo: error: %s: Unable to upload branch "%s". '
                        "You might be able to fix the branch by running:\n"
                        "  git branch --set-upstream-to m/%s",
                        project.RelPath(local=opt.this_manifest_only),
                        project.CurrentBranch,
                        project.manifest.branch,
                    )
                elif avail:
                    pending.append((project, avail))
            return pending

        with self.ParallelContext():
            self.get_parallel_context()["projects"] = projects
            pending = self.ExecuteInParallel(
                opt.jobs,
                functools.partial(self._GatherOne, opt),
                range(len(projects)),
                callback=_ProcessResults,
            )

        if not pending:
            if opt.branch is None:
                logger.error("repo: error: no branches ready for upload")
            else:
                logger.error(
                    'repo: error: no branches named "%s" ready for upload',
                    opt.branch,
                )
            return 1

        manifests = {
            project.manifest.topdir: project.manifest
            for (project, available) in pending
        }
        ret = 0
        for manifest in manifests.values():
            pending_proj_names = [
                project.name
                for (project, available) in pending
                if project.manifest.topdir == manifest.topdir
            ]
            pending_worktrees = [
                project.worktree
                for (project, available) in pending
                if project.manifest.topdir == manifest.topdir
            ]
            hook = RepoHook.FromSubcmd(
                hook_type="pre-upload",
                manifest=manifest,
                opt=opt,
                abort_if_user_denies=True,
            )
            if not hook.Run(
                project_list=pending_proj_names, worktree_list=pending_worktrees
            ):
                if LocalSyncState(manifest).IsPartiallySynced():
                    logger.info(
                        "Tip: A partially synced tree was detected. "
                        "If this failure involves cross-project dependencies, "
                        "a full `repo sync` might help."
                    )
                ret = 1
        if ret:
            return ret

        reviewers = _SplitEmails(opt.reviewers) if opt.reviewers else []
        cc = _SplitEmails(opt.cc) if opt.cc else []
        people = (reviewers, cc)

        if len(pending) == 1 and len(pending[0][1]) == 1:
            self._SingleBranch(opt, pending[0][1][0], people)
        else:
            self._MultipleBranches(opt, pending, people)
