# 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.

from collections import defaultdict
import functools
import itertools
import sys

from command import Command, DEFAULT_LOCAL_JOBS
from git_command import git
from progress import Progress


class Abandon(Command):
    COMMON = True
    helpSummary = "Permanently abandon a development branch"
    helpUsage = """
%prog [--all | <branchname>] [<project>...]

This subcommand permanently abandons a development branch by
deleting it (and all its history) from your local repository.

It is equivalent to "git branch -D <branchname>".
"""
    PARALLEL_JOBS = DEFAULT_LOCAL_JOBS

    def _Options(self, p):
        p.add_option(
            "--all",
            dest="all",
            action="store_true",
            help="delete all branches in all projects",
        )

    def ValidateOptions(self, opt, args):
        if not opt.all and not args:
            self.Usage()

        if not opt.all:
            nb = args[0]
            if not git.check_ref_format("heads/%s" % nb):
                self.OptionParser.error("'%s' is not a valid branch name" % nb)
        else:
            args.insert(0, "'All local branches'")

    def _ExecuteOne(self, all_branches, nb, project):
        """Abandon one project."""
        if all_branches:
            branches = project.GetBranches()
        else:
            branches = [nb]

        ret = {}
        for name in branches:
            status = project.AbandonBranch(name)
            if status is not None:
                ret[name] = status
        return (ret, project)

    def Execute(self, opt, args):
        nb = args[0]
        err = defaultdict(list)
        success = defaultdict(list)
        all_projects = self.GetProjects(
            args[1:], all_manifests=not opt.this_manifest_only
        )
        _RelPath = lambda p: p.RelPath(local=opt.this_manifest_only)

        def _ProcessResults(_pool, pm, states):
            for results, project in states:
                for branch, status in results.items():
                    if status:
                        success[branch].append(project)
                    else:
                        err[branch].append(project)
                pm.update()

        self.ExecuteInParallel(
            opt.jobs,
            functools.partial(self._ExecuteOne, opt.all, nb),
            all_projects,
            callback=_ProcessResults,
            output=Progress(
                "Abandon %s" % (nb,), len(all_projects), quiet=opt.quiet
            ),
        )

        width = max(
            itertools.chain(
                [25], (len(x) for x in itertools.chain(success, err))
            )
        )
        if err:
            for br in err.keys():
                err_msg = "error: cannot abandon %s" % br
                print(err_msg, file=sys.stderr)
                for proj in err[br]:
                    print(
                        " " * len(err_msg) + " | %s" % _RelPath(proj),
                        file=sys.stderr,
                    )
            sys.exit(1)
        elif not success:
            print(
                "error: no project has local branch(es) : %s" % nb,
                file=sys.stderr,
            )
            sys.exit(1)
        else:
            # Everything below here is displaying status.
            if opt.quiet:
                return
            print("Abandoned branches:")
            for br in success.keys():
                if len(all_projects) > 1 and len(all_projects) == len(
                    success[br]
                ):
                    result = "all project"
                else:
                    result = "%s" % (
                        ("\n" + " " * width + "| ").join(
                            _RelPath(p) for p in success[br]
                        )
                    )
                print("%s%s| %s\n" % (br, " " * (width - len(br)), result))
