# -*- coding:utf-8 -*-
#
# 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.

from __future__ import print_function
import sys
from color import Coloring
from command import Command

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.

"""

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

    for project in projects:
      for name, b in project.GetBranches().items():
        b.project = project
        if name not in all_branches:
          all_branches[name] = BranchInfo(name)
        all_branches[name].add(b)

    names = list(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(' |')

      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:
            if not i.IsSplitCurrent or b.current:
              paths.append(b.project.relpath)
            else:
              non_cur_paths.append(b.project.relpath)
        else:
          fmt = out.notinproject
          in_type = 'not in'
          have = set()
          for b in i.projects:
            have.add(b.project)
          for p in projects:
            if p not in have:
              paths.append(p.relpath)

        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()
