# 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 = b.project.relpath
            if not i.IsSplitCurrent or b.current:
              paths.append(_RelPath(b.project))
            else:
              non_cur_paths.append(_RelPath(b.project))
        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
