# Copyright (C) 2009 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 itertools
import sys

from color import Coloring
from command import Command, DEFAULT_LOCAL_JOBS


class BranchColoring(Coloring):
    def __init__(self, config):
        Coloring.__init__(self, config, "branch")
        self.current = self.printer("current", fg="green")
        self.local = self.printer("local")
        self.notinproject = self.printer("notinproject", fg="red")


class BranchInfo(object):
    def __init__(self, name):
        self.name = name
        self.current = 0
        self.published = 0
        self.published_equal = 0
        self.projects = []

    def add(self, b):
        if b.current:
            self.current += 1
        if b.published:
            self.published += 1
        if b.revision == b.published:
            self.published_equal += 1
        self.projects.append(b)

    @property
    def IsCurrent(self):
        return self.current > 0

    @property
    def IsSplitCurrent(self):
        return self.current != 0 and self.current != len(self.projects)

    @property
    def IsPublished(self):
        return self.published > 0

    @property
    def IsPublishedEqual(self):
        return self.published_equal == len(self.projects)


class Branches(Command):
    COMMON = True
    helpSummary = "View current topic branches"
    helpUsage = """
%prog [<project>...]

Summarizes the currently available topic branches.

# Branch Display

The branch display output by this command is organized into four
columns of information; for example:

 *P nocolor                   | in repo
    repo2                     |

The first column contains a * if the branch is the currently
checked out branch in any of the specified projects, or a blank
if no project has the branch checked out.

The second column contains either blank, p or P, depending upon
the upload status of the branch.

 (blank): branch not yet published by repo upload
       P: all commits were published by repo upload
       p: only some commits were published by repo upload

The third column contains the branch name.

The fourth column (after the | separator) lists the projects that
the branch appears in, or does not appear in.  If no project list
is shown, then the branch appears in all projects.

"""
    PARALLEL_JOBS = DEFAULT_LOCAL_JOBS

    def Execute(self, opt, args):
        projects = self.GetProjects(
            args, all_manifests=not opt.this_manifest_only
        )
        out = BranchColoring(self.manifest.manifestProject.config)
        all_branches = {}
        project_cnt = len(projects)

        def _ProcessResults(_pool, _output, results):
            for name, b in itertools.chain.from_iterable(results):
                if name not in all_branches:
                    all_branches[name] = BranchInfo(name)
                all_branches[name].add(b)

        self.ExecuteInParallel(
            opt.jobs,
            expand_project_to_branches,
            projects,
            callback=_ProcessResults,
        )

        names = sorted(all_branches)

        if not names:
            print("   (no branches)", file=sys.stderr)
            return

        width = 25
        for name in names:
            if width < len(name):
                width = len(name)

        for name in names:
            i = all_branches[name]
            in_cnt = len(i.projects)

            if i.IsCurrent:
                current = "*"
                hdr = out.current
            else:
                current = " "
                hdr = out.local

            if i.IsPublishedEqual:
                published = "P"
            elif i.IsPublished:
                published = "p"
            else:
                published = " "

            hdr("%c%c %-*s" % (current, published, width, name))
            out.write(" |")

            _RelPath = lambda p: p.RelPath(local=opt.this_manifest_only)
            if in_cnt < project_cnt:
                fmt = out.write
                paths = []
                non_cur_paths = []
                if i.IsSplitCurrent or (in_cnt <= project_cnt - in_cnt):
                    in_type = "in"
                    for b in i.projects:
                        relpath = _RelPath(b.project)
                        if not i.IsSplitCurrent or b.current:
                            paths.append(relpath)
                        else:
                            non_cur_paths.append(relpath)
                else:
                    fmt = out.notinproject
                    in_type = "not in"
                    have = set()
                    for b in i.projects:
                        have.add(_RelPath(b.project))
                    for p in projects:
                        if _RelPath(p) not in have:
                            paths.append(_RelPath(p))

                s = " %s %s" % (in_type, ", ".join(paths))
                if not i.IsSplitCurrent and (width + 7 + len(s) < 80):
                    fmt = out.current if i.IsCurrent else fmt
                    fmt(s)
                else:
                    fmt(" %s:" % in_type)
                    fmt = out.current if i.IsCurrent else out.write
                    for p in paths:
                        out.nl()
                        fmt(width * " " + "          %s" % p)
                    fmt = out.write
                    for p in non_cur_paths:
                        out.nl()
                        fmt(width * " " + "          %s" % p)
            else:
                out.write(" in all projects")
            out.nl()


def expand_project_to_branches(project):
    """Expands a project into a list of branch names & associated information.

    Args:
        project: project.Project

    Returns:
        List[Tuple[str, git_config.Branch]]
    """
    branches = []
    for name, b in project.GetBranches().items():
        b.project = project
        branches.append((name, b))
    return branches
