# Copyright (C) 2008 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 re
import sys
import textwrap

from subcmds import all_commands
from color import Coloring
from command import PagedCommand, MirrorSafeCommand, GitcAvailableCommand, GitcClientCommand
import gitc_utils
from wrapper import Wrapper


class Help(PagedCommand, MirrorSafeCommand):
  COMMON = False
  helpSummary = "Display detailed help on a command"
  helpUsage = """
%prog [--all|command]
"""
  helpDescription = """
Displays detailed usage information about a command.
"""

  def _PrintCommands(self, commandNames):
    """Helper to display |commandNames| summaries."""
    maxlen = 0
    for name in commandNames:
      maxlen = max(maxlen, len(name))
    fmt = '  %%-%ds  %%s' % maxlen

    for name in commandNames:
      command = all_commands[name]()
      try:
        summary = command.helpSummary.strip()
      except AttributeError:
        summary = ''
      print(fmt % (name, summary))

  def _PrintAllCommands(self):
    print('usage: repo COMMAND [ARGS]')
    print('The complete list of recognized repo commands are:')
    commandNames = list(sorted(all_commands))
    self._PrintCommands(commandNames)
    print("See 'repo help <command>' for more information on a "
          'specific command.')

  def _PrintCommonCommands(self):
    print('usage: repo COMMAND [ARGS]')
    print('The most commonly used repo commands are:')

    def gitc_supported(cmd):
      if not isinstance(cmd, GitcAvailableCommand) and not isinstance(cmd, GitcClientCommand):
        return True
      if self.client.isGitcClient:
        return True
      if isinstance(cmd, GitcClientCommand):
        return False
      if gitc_utils.get_gitc_manifest_dir():
        return True
      return False

    commandNames = list(sorted([name
                                for name, command in all_commands.items()
                                if command.COMMON and gitc_supported(command)]))
    self._PrintCommands(commandNames)

    print(
        "See 'repo help <command>' for more information on a specific command.\n"
        "See 'repo help --all' for a complete list of recognized commands.")
    print('Bug reports:', Wrapper().BUG_URL)

  def _PrintCommandHelp(self, cmd, header_prefix=''):
    class _Out(Coloring):
      def __init__(self, gc):
        Coloring.__init__(self, gc, 'help')
        self.heading = self.printer('heading', attr='bold')
        self._first = True

      def _PrintSection(self, heading, bodyAttr):
        try:
          body = getattr(cmd, bodyAttr)
        except AttributeError:
          return
        if body == '' or body is None:
          return

        if not self._first:
          self.nl()
        self._first = False

        self.heading('%s%s', header_prefix, heading)
        self.nl()
        self.nl()

        me = 'repo %s' % cmd.NAME
        body = body.strip()
        body = body.replace('%prog', me)

        # Extract the title, but skip any trailing {#anchors}.
        asciidoc_hdr = re.compile(r'^\n?#+ ([^{]+)(\{#.+\})?$')
        for para in body.split("\n\n"):
          if para.startswith(' '):
            self.write('%s', para)
            self.nl()
            self.nl()
            continue

          m = asciidoc_hdr.match(para)
          if m:
            self.heading('%s%s', header_prefix, m.group(1))
            self.nl()
            self.nl()
            continue

          lines = textwrap.wrap(para.replace('  ', ' '), width=80,
                                break_long_words=False, break_on_hyphens=False)
          for line in lines:
            self.write('%s', line)
            self.nl()
          self.nl()

    out = _Out(self.client.globalConfig)
    out._PrintSection('Summary', 'helpSummary')
    cmd.OptionParser.print_help()
    out._PrintSection('Description', 'helpDescription')

  def _PrintAllCommandHelp(self):
    for name in sorted(all_commands):
      cmd = all_commands[name]()
      cmd.manifest = self.manifest
      self._PrintCommandHelp(cmd, header_prefix='[%s] ' % (name,))

  def _Options(self, p):
    p.add_option('-a', '--all',
                 dest='show_all', action='store_true',
                 help='show the complete list of commands')
    p.add_option('--help-all',
                 dest='show_all_help', action='store_true',
                 help='show the --help of all commands')

  def Execute(self, opt, args):
    if len(args) == 0:
      if opt.show_all_help:
        self._PrintAllCommandHelp()
      elif opt.show_all:
        self._PrintAllCommands()
      else:
        self._PrintCommonCommands()

    elif len(args) == 1:
      name = args[0]

      try:
        cmd = all_commands[name]()
      except KeyError:
        print("repo: '%s' is not a repo command." % name, file=sys.stderr)
        sys.exit(1)

      cmd.manifest = self.manifest
      self._PrintCommandHelp(cmd)

    else:
      self._PrintCommandHelp(self)
