# Copyright (C) 2012 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 optparse

from command import PagedCommand
from color import Coloring
from git_refs import R_M, R_HEADS


class _Coloring(Coloring):
  def __init__(self, config):
    Coloring.__init__(self, config, "status")


class Info(PagedCommand):
  COMMON = True
  helpSummary = "Get info on the manifest branch, current branch or unmerged branches"
  helpUsage = "%prog [-dl] [-o [-c]] [<project>...]"

  def _Options(self, p):
    p.add_option('-d', '--diff',
                 dest='all', action='store_true',
                 help="show full info and commit diff including remote branches")
    p.add_option('-o', '--overview',
                 dest='overview', action='store_true',
                 help='show overview of all local commits')
    p.add_option('-c', '--current-branch',
                 dest="current_branch", action="store_true",
                 help="consider only checked out branches")
    p.add_option('--no-current-branch',
                 dest='current_branch', action='store_false',
                 help='consider all local branches')
    # Turn this into a warning & remove this someday.
    p.add_option('-b',
                 dest='current_branch', action='store_true',
                 help=optparse.SUPPRESS_HELP)
    p.add_option('-l', '--local-only',
                 dest="local", action="store_true",
                 help="disable all remote operations")

  def Execute(self, opt, args):
    self.out = _Coloring(self.client.globalConfig)
    self.heading = self.out.printer('heading', attr='bold')
    self.headtext = self.out.nofmt_printer('headtext', fg='yellow')
    self.redtext = self.out.printer('redtext', fg='red')
    self.sha = self.out.printer("sha", fg='yellow')
    self.text = self.out.nofmt_printer('text')
    self.dimtext = self.out.printer('dimtext', attr='dim')

    self.opt = opt

    manifestConfig = self.manifest.manifestProject.config
    mergeBranch = manifestConfig.GetBranch("default").merge
    manifestGroups = (manifestConfig.GetString('manifest.groups')
                      or 'all,-notdefault')

    self.heading("Manifest branch: ")
    if self.manifest.default.revisionExpr:
        self.headtext(self.manifest.default.revisionExpr)
    self.out.nl()
    self.heading("Manifest merge branch: ")
    self.headtext(mergeBranch)
    self.out.nl()
    self.heading("Manifest groups: ")
    self.headtext(manifestGroups)
    self.out.nl()

    self.printSeparator()

    if not opt.overview:
      self.printDiffInfo(args)
    else:
      self.printCommitOverview(args)

  def printSeparator(self):
    self.text("----------------------------")
    self.out.nl()

  def printDiffInfo(self, args):
    # We let exceptions bubble up to main as they'll be well structured.
    projs = self.GetProjects(args)

    for p in projs:
      self.heading("Project: ")
      self.headtext(p.name)
      self.out.nl()

      self.heading("Mount path: ")
      self.headtext(p.worktree)
      self.out.nl()

      self.heading("Current revision: ")
      self.headtext(p.GetRevisionId())
      self.out.nl()

      currentBranch = p.CurrentBranch
      if currentBranch:
        self.heading('Current branch: ')
        self.headtext(currentBranch)
        self.out.nl()

      self.heading("Manifest revision: ")
      self.headtext(p.revisionExpr)
      self.out.nl()

      localBranches = list(p.GetBranches().keys())
      self.heading("Local Branches: ")
      self.redtext(str(len(localBranches)))
      if localBranches:
        self.text(" [")
        self.text(", ".join(localBranches))
        self.text("]")
      self.out.nl()

      if self.opt.all:
        self.findRemoteLocalDiff(p)

      self.printSeparator()

  def findRemoteLocalDiff(self, project):
    # Fetch all the latest commits.
    if not self.opt.local:
      project.Sync_NetworkHalf(quiet=True, current_branch_only=True)

    branch = self.manifest.manifestProject.config.GetBranch('default').merge
    if branch.startswith(R_HEADS):
      branch = branch[len(R_HEADS):]
    logTarget = R_M + branch

    bareTmp = project.bare_git._bare
    project.bare_git._bare = False
    localCommits = project.bare_git.rev_list(
        '--abbrev=8',
        '--abbrev-commit',
        '--pretty=oneline',
        logTarget + "..",
        '--')

    originCommits = project.bare_git.rev_list(
        '--abbrev=8',
        '--abbrev-commit',
        '--pretty=oneline',
        ".." + logTarget,
        '--')
    project.bare_git._bare = bareTmp

    self.heading("Local Commits: ")
    self.redtext(str(len(localCommits)))
    self.dimtext(" (on current branch)")
    self.out.nl()

    for c in localCommits:
      split = c.split()
      self.sha(split[0] + " ")
      self.text(" ".join(split[1:]))
      self.out.nl()

    self.printSeparator()

    self.heading("Remote Commits: ")
    self.redtext(str(len(originCommits)))
    self.out.nl()

    for c in originCommits:
      split = c.split()
      self.sha(split[0] + " ")
      self.text(" ".join(split[1:]))
      self.out.nl()

  def printCommitOverview(self, args):
    all_branches = []
    for project in self.GetProjects(args):
      br = [project.GetUploadableBranch(x)
            for x in project.GetBranches()]
      br = [x for x in br if x]
      if self.opt.current_branch:
        br = [x for x in br if x.name == project.CurrentBranch]
      all_branches.extend(br)

    if not all_branches:
      return

    self.out.nl()
    self.heading('Projects Overview')
    project = None

    for branch in all_branches:
      if project != branch.project:
        project = branch.project
        self.out.nl()
        self.headtext(project.relpath)
        self.out.nl()

      commits = branch.commits
      date = branch.date
      self.text('%s %-33s (%2d commit%s, %s)' % (
          branch.name == project.CurrentBranch and '*' or ' ',
          branch.name,
          len(commits),
          len(commits) != 1 and 's' or '',
          date))
      self.out.nl()

      for commit in commits:
        split = commit.split()
        self.text('{0:38}{1} '.format('', '-'))
        self.sha(split[0] + " ")
        self.text(" ".join(split[1:]))
        self.out.nl()
