# Copyright (C) 2010 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 sys

from color import Coloring
from command import Command
from git_command import GitCommand
from repo_logging import RepoLogger


logger = RepoLogger(__file__)


class RebaseColoring(Coloring):
    def __init__(self, config):
        Coloring.__init__(self, config, "rebase")
        self.project = self.printer("project", attr="bold")
        self.fail = self.printer("fail", fg="red")


class Rebase(Command):
    COMMON = True
    helpSummary = "Rebase local branches on upstream branch"
    helpUsage = """
%prog {[<project>...] | -i <project>...}
"""
    helpDescription = """
'%prog' uses git rebase to move local changes in the current topic branch to
the HEAD of the upstream history, useful when you have made commits in a topic
branch but need to incorporate new upstream changes "underneath" them.
"""

    def _Options(self, p):
        g = p.get_option_group("--quiet")
        g.add_option(
            "-i",
            "--interactive",
            dest="interactive",
            action="store_true",
            help="interactive rebase (single project only)",
        )

        p.add_option(
            "--fail-fast",
            dest="fail_fast",
            action="store_true",
            help="stop rebasing after first error is hit",
        )
        p.add_option(
            "-f",
            "--force-rebase",
            dest="force_rebase",
            action="store_true",
            help="pass --force-rebase to git rebase",
        )
        p.add_option(
            "--no-ff",
            dest="ff",
            default=True,
            action="store_false",
            help="pass --no-ff to git rebase",
        )
        p.add_option(
            "--autosquash",
            dest="autosquash",
            action="store_true",
            help="pass --autosquash to git rebase",
        )
        p.add_option(
            "--whitespace",
            dest="whitespace",
            action="store",
            metavar="WS",
            help="pass --whitespace to git rebase",
        )
        p.add_option(
            "--auto-stash",
            dest="auto_stash",
            action="store_true",
            help="stash local modifications before starting",
        )
        p.add_option(
            "-m",
            "--onto-manifest",
            dest="onto_manifest",
            action="store_true",
            help="rebase onto the manifest version instead of upstream "
            "HEAD (this helps to make sure the local tree stays "
            "consistent if you previously synced to a manifest)",
        )

    def Execute(self, opt, args):
        all_projects = self.GetProjects(
            args, all_manifests=not opt.this_manifest_only
        )
        one_project = len(all_projects) == 1

        if opt.interactive and not one_project:
            logger.error(
                "error: interactive rebase not supported with multiple projects"
            )

            if len(args) == 1:
                logger.warning(
                    "note: project %s is mapped to more than one path", args[0]
                )

            return 1

        # Setup the common git rebase args that we use for all projects.
        common_args = ["rebase"]
        if opt.whitespace:
            common_args.append("--whitespace=%s" % opt.whitespace)
        if opt.quiet:
            common_args.append("--quiet")
        if opt.force_rebase:
            common_args.append("--force-rebase")
        if not opt.ff:
            common_args.append("--no-ff")
        if opt.autosquash:
            common_args.append("--autosquash")
        if opt.interactive:
            common_args.append("-i")

        config = self.manifest.manifestProject.config
        out = RebaseColoring(config)
        out.redirect(sys.stdout)
        _RelPath = lambda p: p.RelPath(local=opt.this_manifest_only)

        ret = 0
        for project in all_projects:
            if ret and opt.fail_fast:
                break

            cb = project.CurrentBranch
            if not cb:
                if one_project:
                    logger.error(
                        "error: project %s has a detached HEAD",
                        _RelPath(project),
                    )
                    return 1
                # Ignore branches with detached HEADs.
                continue

            upbranch = project.GetBranch(cb)
            if not upbranch.LocalMerge:
                if one_project:
                    logger.error(
                        "error: project %s does not track any remote branches",
                        _RelPath(project),
                    )
                    return 1
                # Ignore branches without remotes.
                continue

            args = common_args[:]
            if opt.onto_manifest:
                args.append("--onto")
                args.append(project.revisionExpr)

            args.append(upbranch.LocalMerge)

            out.project(
                "project %s: rebasing %s -> %s",
                _RelPath(project),
                cb,
                upbranch.LocalMerge,
            )
            out.nl()
            out.flush()

            needs_stash = False
            if opt.auto_stash:
                stash_args = ["update-index", "--refresh", "-q"]

                if GitCommand(project, stash_args).Wait() != 0:
                    needs_stash = True
                    # Dirty index, requires stash...
                    stash_args = ["stash"]

                    if GitCommand(project, stash_args).Wait() != 0:
                        ret += 1
                        continue

            if GitCommand(project, args).Wait() != 0:
                ret += 1
                continue

            if needs_stash:
                stash_args.append("pop")
                stash_args.append("--quiet")
                if GitCommand(project, stash_args).Wait() != 0:
                    ret += 1

        if ret:
            msg_fmt = "%d projects had errors"
            self.git_event_log.ErrorEvent(msg_fmt % (ret), msg_fmt)
            out.fail(msg_fmt, ret)
            out.nl()

        return ret
