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

from command import PagedCommand
from color import Coloring
from error import NoSuchProjectError
from git_refs import R_M


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 [-b]] [<project>...]"

    def _Options(self, p, show_smart=True):
        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('-b', '--current-branch',
                     dest="current_branch", action="store_true",
                     help="consider only checked out branches")
        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.manifest.globalConfig)
        self.heading = self.out.printer('heading', attr='bold')
        self.headtext = self.out.printer('headtext', fg='yellow')
        self.redtext = self.out.printer('redtext', fg='red')
        self.sha = self.out.printer("sha", fg='yellow')
        self.text = self.out.printer('text')
        self.dimtext = self.out.printer('dimtext', attr='dim')

        self.opt = opt

        mergeBranch = self.manifest.manifestProject.config.GetBranch("default").merge

        self.heading("Manifest branch: ")
        self.headtext(self.manifest.default.revisionExpr)
        self.out.nl()
        self.heading("Manifest merge branch: ")
        self.headtext(mergeBranch)
        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):
        try:
            projs = self.GetProjects(args)
        except NoSuchProjectError:
            return

        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.revisionExpr)
            self.out.nl()

            localBranches = list(p.GetBranches().keys())
            self.heading("Local Branches: ")
            self.redtext(str(len(localBranches)))
            if len(localBranches) > 0:
                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)

        logTarget = R_M + self.manifest.manifestProject.config.GetBranch("default").merge

        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.decode('UTF-8').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.decode('UTF-8').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 list(project.GetBranches().keys())]
            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.decode('UTF-8').split()
                self.text('{0:38}{1} '.format('', '-'))
                self.sha(split[0] + " ")
                self.text(" ".join(split[1:]))
                self.out.nl()
