#!/usr/bin/env python
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Parse a command line, retrieving a command and its arguments.

Supports the concept of command line commands, each with its own set
of arguments. Supports dependent arguments and mutually exclusive arguments.
Basically, a better optparse. I took heed of epg's WHINE() in gvn.cmdline
and dumped optparse in favor of something better.
"""

import os.path
import re
import string
import sys
import textwrap
import types


def IsString(var):
  """Little helper function to see if a variable is a string."""
  return type(var) in types.StringTypes


class ParseError(Exception):
  """Encapsulates errors from parsing, string arg is description."""
  pass


class Command(object):
  """Implements a single command."""

  def __init__(self, names, helptext, validator=None, impl=None):
    """Initializes Command from names and helptext, plus optional callables.

    Args:
      names:       command name, or list of synonyms
      helptext:    brief string description of the command
      validator:   callable for custom argument validation
                   Should raise ParseError if it wants
      impl:        callable to be invoked when command is called
    """
    self.names = names
    self.validator = validator
    self.helptext = helptext
    self.impl = impl
    self.args = []
    self.required_groups = []
    self.arg_dict = {}
    self.positional_args = []
    self.cmdline = None

  class Argument(object):
    """Encapsulates an argument to a command."""
    VALID_TYPES = ['string', 'readfile', 'int', 'flag', 'coords']
    TYPES_WITH_VALUES = ['string', 'readfile', 'int', 'coords']

    def __init__(self, names, helptext, type, metaname,
                 required, default, positional):
      """Command-line argument to a command.

      Args:
        names:       argument name, or list of synonyms
        helptext:    brief description of the argument
        type:        type of the argument. Valid values include:
                          string - a string
                          readfile - a file which must exist and be available
                            for reading
                          int - an integer
                          flag - an optional flag (bool)
                          coords - (x,y) where x and y are ints
        metaname:    Name to display for value in help, inferred if not
                     specified
        required:    True if argument must be specified
        default:     Default value if not specified
        positional:  Argument specified by location, not name

      Raises:
        ValueError: the argument name is invalid for some reason
      """
      if type not in Command.Argument.VALID_TYPES:
        raise ValueError("Invalid type: %r" % type)

      if required and default is not None:
        raise ValueError("required and default are mutually exclusive")

      if required and type == 'flag':
        raise ValueError("A required flag? Give me a break.")

      if metaname and type not in Command.Argument.TYPES_WITH_VALUES:
        raise ValueError("Type %r can't have a metaname" % type)

      # If no metaname is provided, infer it: use the alphabetical characters
      # of the last provided name
      if not metaname and type in Command.Argument.TYPES_WITH_VALUES:
        metaname = (
          names[-1].lstrip(string.punctuation + string.whitespace).upper())

      self.names = names
      self.helptext = helptext
      self.type = type
      self.required = required
      self.default = default
      self.positional = positional
      self.metaname = metaname

      self.mutex = []          # arguments that are mutually exclusive with
                               # this one
      self.depends = []        # arguments that must be present for this
                               # one to be valid
      self.present = False     # has this argument been specified?

    def AddDependency(self, arg):
      """Makes this argument dependent on another argument.

      Args:
        arg: name of the argument this one depends on
      """
      if arg not in self.depends:
        self.depends.append(arg)

    def AddMutualExclusion(self, arg):
      """Makes this argument invalid if another is specified.

      Args:
        arg: name of the mutually exclusive argument.
      """
      if arg not in self.mutex:
        self.mutex.append(arg)

    def GetUsageString(self):
      """Returns a brief string describing the argument's usage."""
      if not self.positional:
        string = self.names[0]
        if self.type in Command.Argument.TYPES_WITH_VALUES:
          string += "="+self.metaname
      else:
        string = self.metaname

      if not self.required:
        string = "["+string+"]"

      return string

    def GetNames(self):
      """Returns a string containing a list of the arg's names."""
      if self.positional:
        return self.metaname
      else:
        return ", ".join(self.names)

    def GetHelpString(self, width=80, indent=5, names_width=20, gutter=2):
      """Returns a help string including help for all the arguments."""
      names = [" "*indent + line +" "*(names_width-len(line)) for line in
               textwrap.wrap(self.GetNames(), names_width)]

      helpstring = textwrap.wrap(self.helptext, width-indent-names_width-gutter)

      if len(names) < len(helpstring):
        names += [" "*(indent+names_width)]*(len(helpstring)-len(names))

      if len(helpstring) < len(names):
        helpstring += [""]*(len(names)-len(helpstring))

      return "\n".join([name_line + " "*gutter + help_line for
                        name_line, help_line in zip(names, helpstring)])

    def __repr__(self):
      if self.present:
        string = '= %r' % self.value
      else:
        string = "(absent)"

      return "Argument %s '%s'%s" % (self.type, self.names[0], string)

    # end of nested class Argument

  def AddArgument(self, names, helptext, type="string", metaname=None,
                  required=False, default=None, positional=False):
    """Command-line argument to a command.

    Args:
      names:      argument name, or list of synonyms
      helptext:   brief description of the argument
      type:       type of the argument
      metaname:   Name to display for value in help, inferred if not
      required:   True if argument must be specified
      default:    Default value if not specified
      positional: Argument specified by location, not name

    Raises:
      ValueError: the argument already exists or is invalid

    Returns:
      The newly-created argument
    """
    if IsString(names): names = [names]

    names = [name.lower() for name in names]

    for name in names:
      if name in self.arg_dict:
        raise ValueError("%s is already an argument"%name)

    if (positional and required and
        [arg for arg in self.args if arg.positional] and
        not [arg for arg in self.args if arg.positional][-1].required):
      raise ValueError(
        "A required positional argument may not follow an optional one.")

    arg = Command.Argument(names, helptext, type, metaname,
                           required, default, positional)

    self.args.append(arg)

    for name in names:
      self.arg_dict[name] = arg

    return arg

  def GetArgument(self, name):
    """Return an argument from a name."""
    return self.arg_dict[name.lower()]

  def AddMutualExclusion(self, args):
    """Specifies that a list of arguments are mutually exclusive."""
    if len(args) < 2:
      raise ValueError("At least two arguments must be specified.")

    args = [arg.lower() for arg in args]

    for index in xrange(len(args)-1):
      for index2 in xrange(index+1, len(args)):
        self.arg_dict[args[index]].AddMutualExclusion(self.arg_dict[args[index2]])

  def AddDependency(self, dependent, depends_on):
    """Specifies that one argument may only be present if another is.

    Args:
      dependent:  the name of the dependent argument
      depends_on: the name of the argument on which it depends
    """
    self.arg_dict[dependent.lower()].AddDependency(
      self.arg_dict[depends_on.lower()])

  def AddMutualDependency(self, args):
    """Specifies that a list of arguments are all mutually dependent."""
    if len(args) < 2:
      raise ValueError("At least two arguments must be specified.")

    args = [arg.lower() for arg in args]

    for (arg1, arg2) in [(arg1, arg2) for arg1 in args for arg2 in args]:
      if arg1 == arg2: continue
      self.arg_dict[arg1].AddDependency(self.arg_dict[arg2])

  def AddRequiredGroup(self, args):
    """Specifies that at least one of the named arguments must be present."""
    if len(args) < 2:
      raise ValueError("At least two arguments must be in a required group.")

    args = [self.arg_dict[arg.lower()] for arg in args]

    self.required_groups.append(args)

  def ParseArguments(self):
    """Given a command line, parse and validate the arguments."""

    # reset all the arguments before we parse
    for arg in self.args:
      arg.present = False
      arg.value = None

    self.parse_errors = []

    # look for arguments remaining on the command line
    while len(self.cmdline.rargs):
      try:
        self.ParseNextArgument()
      except ParseError, e:
        self.parse_errors.append(e.args[0])

    # after all the arguments are parsed, check for problems
    for arg in self.args:
      if not arg.present and arg.required:
        self.parse_errors.append("'%s': required parameter was missing"
                                 % arg.names[0])

      if not arg.present and arg.default:
        arg.present = True
        arg.value = arg.default

      if arg.present:
        for mutex in arg.mutex:
          if mutex.present:
            self.parse_errors.append(
              "'%s', '%s': arguments are mutually exclusive" %
              (arg.argstr, mutex.argstr))

        for depend in arg.depends:
          if not depend.present:
            self.parse_errors.append("'%s': '%s' must be specified as well" %
                                     (arg.argstr, depend.names[0]))

    # check for required groups
    for group in self.required_groups:
      if not [arg for arg in group if arg.present]:
        self.parse_errors.append("%s: at least one must be present" %
                         (", ".join(["'%s'" % arg.names[-1] for arg in group])))

    # if we have any validators, invoke them
    if not self.parse_errors and self.validator:
      try:
        self.validator(self)
      except ParseError, e:
        self.parse_errors.append(e.args[0])

  # Helper methods so you can treat the command like a dict
  def __getitem__(self, key):
    arg = self.arg_dict[key.lower()]

    if arg.type == 'flag':
      return arg.present
    else:
      return arg.value

  def __iter__(self):
    return [arg for arg in self.args if arg.present].__iter__()

  def ArgumentPresent(self, key):
    """Tests if an argument exists and has been specified."""
    return key.lower() in self.arg_dict and self.arg_dict[key.lower()].present

  def __contains__(self, key):
    return self.ArgumentPresent(key)

  def ParseNextArgument(self):
    """Find the next argument in the command line and parse it."""
    arg = None
    value = None
    argstr = self.cmdline.rargs.pop(0)

    # First check: is this a literal argument?
    if argstr.lower() in self.arg_dict:
      arg = self.arg_dict[argstr.lower()]
      if arg.type in Command.Argument.TYPES_WITH_VALUES:
        if len(self.cmdline.rargs):
          value = self.cmdline.rargs.pop(0)

    # Second check: is this of the form "arg=val" or "arg:val"?
    if arg is None:
      delimiter_pos = -1

      for delimiter in [':', '=']:
        pos = argstr.find(delimiter)
        if pos >= 0:
          if delimiter_pos < 0 or pos < delimiter_pos:
            delimiter_pos = pos

      if delimiter_pos >= 0:
        testarg = argstr[:delimiter_pos]
        testval = argstr[delimiter_pos+1:]

        if testarg.lower() in self.arg_dict:
          arg = self.arg_dict[testarg.lower()]
          argstr = testarg
          value = testval

    # Third check: does this begin an argument?
    if arg is None:
      for key in self.arg_dict.iterkeys():
        if (len(key) < len(argstr) and
            self.arg_dict[key].type in Command.Argument.TYPES_WITH_VALUES and
            argstr[:len(key)].lower() == key):
          value = argstr[len(key):]
          argstr = argstr[:len(key)]
          arg = self.arg_dict[argstr]

    # Fourth check: do we have any positional arguments available?
    if arg is None:
      for positional_arg in [
          testarg for testarg in self.args if testarg.positional]:
        if not positional_arg.present:
          arg = positional_arg
          value = argstr
          argstr = positional_arg.names[0]
          break

    # Push the retrieved argument/value onto the largs stack
    if argstr: self.cmdline.largs.append(argstr)
    if value:  self.cmdline.largs.append(value)

    # If we've made it this far and haven't found an arg, give up
    if arg is None:
      raise ParseError("Unknown argument: '%s'" % argstr)

    # Convert the value, if necessary
    if arg.type in Command.Argument.TYPES_WITH_VALUES and value is None:
      raise ParseError("Argument '%s' requires a value" % argstr)

    if value is not None:
      value = self.StringToValue(value, arg.type, argstr)

    arg.argstr = argstr
    arg.value = value
    arg.present = True

    # end method ParseNextArgument

  def StringToValue(self, value, type, argstr):
    """Convert a string from the command line to a value type."""
    try:
      if type == 'string':
        pass  # leave it be

      elif type == 'int':
        try:
          value = int(value)
        except ValueError:
          raise ParseError

      elif type == 'readfile':
        if not os.path.isfile(value):
          raise ParseError("'%s': '%s' does not exist" % (argstr, value))

      elif type == 'coords':
        try:
          value = [int(val) for val in
                   re.match("\(\s*(\d+)\s*\,\s*(\d+)\s*\)\s*\Z", value).
                   groups()]
        except AttributeError:
          raise ParseError

      else:
        raise ValueError("Unknown type: '%s'" % type)

    except ParseError, e:
      # The bare exception is raised in the generic case; more specific errors
      # will arrive with arguments and should just be reraised
      if not e.args:
        e = ParseError("'%s': unable to convert '%s' to type '%s'" %
                       (argstr, value, type))
      raise e

    return value

  def SortArgs(self):
    """Returns a method that can be passed to sort() to sort arguments."""

    def ArgSorter(arg1, arg2):
      """Helper for sorting arguments in the usage string.

      Positional arguments come first, then required arguments,
      then optional arguments. Pylint demands this trivial function
      have both Args: and Returns: sections, sigh.

      Args:
        arg1: the first argument to compare
        arg2: the second argument to compare

      Returns:
        -1 if arg1 should be sorted first, +1 if it should be sorted second,
        and 0 if arg1 and arg2 have the same sort level.
      """
      return ((arg2.positional-arg1.positional)*2 +
              (arg2.required-arg1.required))
    return ArgSorter

  def GetUsageString(self, width=80, name=None):
    """Gets a string describing how the command is used."""
    if name is None: name = self.names[0]

    initial_indent = "Usage: %s %s " % (self.cmdline.prog, name)
    subsequent_indent = " " * len(initial_indent)

    sorted_args = self.args[:]
    sorted_args.sort(self.SortArgs())

    return textwrap.fill(
      " ".join([arg.GetUsageString() for arg in sorted_args]), width,
      initial_indent=initial_indent,
      subsequent_indent=subsequent_indent)

  def GetHelpString(self, width=80):
    """Returns a list of help strings for all this command's arguments."""
    sorted_args = self.args[:]
    sorted_args.sort(self.SortArgs())

    return "\n".join([arg.GetHelpString(width) for arg in sorted_args])

  # end class Command


class CommandLine(object):
  """Parse a command line, extracting a command and its arguments."""

  def __init__(self):
    self.commands = []
    self.cmd_dict = {}

    # Add the help command to the parser
    help_cmd = self.AddCommand(["help", "--help", "-?", "-h"],
                               "Displays help text for a command",
                               ValidateHelpCommand,
                               DoHelpCommand)

    help_cmd.AddArgument(
      "command", "Command to retrieve help for", positional=True)
    help_cmd.AddArgument(
      "--width", "Width of the output", type='int', default=80)

    self.Exit = sys.exit   # override this if you don't want the script to halt
                           # on error or on display of help

    self.out = sys.stdout  # override these if you want to redirect
    self.err = sys.stderr  # output or error messages

  def AddCommand(self, names, helptext, validator=None, impl=None):
    """Add a new command to the parser.

    Args:
      names:       command name, or list of synonyms
      helptext:    brief string description of the command
      validator:   method to validate a command's arguments
      impl:        callable to be invoked when command is called

    Raises:
      ValueError: raised if command already added

    Returns:
      The new command
    """
    if IsString(names): names = [names]

    for name in names:
      if name in self.cmd_dict:
        raise ValueError("%s is already a command"%name)

    cmd = Command(names, helptext, validator, impl)
    cmd.cmdline = self

    self.commands.append(cmd)
    for name in names:
      self.cmd_dict[name.lower()] = cmd

    return cmd

  def GetUsageString(self):
    """Returns simple usage instructions."""
    return "Type '%s help' for usage." % self.prog

  def ParseCommandLine(self, argv=None, prog=None, execute=True):
    """Does the work of parsing a command line.

    Args:
      argv:     list of arguments, defaults to sys.args[1:]
      prog:     name of the command, defaults to the base name of the script
      execute:  if false, just parse, don't invoke the 'impl' member

    Returns:
      The command that was executed
    """
    if argv is None: argv = sys.argv[1:]
    if prog is None: prog = os.path.basename(sys.argv[0]).split('.')[0]

    # Store off our parameters, we may need them someday
    self.argv = argv
    self.prog = prog

    # We shouldn't be invoked without arguments, that's just lame
    if not len(argv):
      self.out.writelines(self.GetUsageString())
      self.Exit()
      return None   # in case the client overrides Exit

    # Is it a valid command?
    self.command_string = argv[0].lower()
    if not self.command_string in self.cmd_dict:
      self.err.write("Unknown command: '%s'\n\n" % self.command_string)
      self.out.write(self.GetUsageString())
      self.Exit()
      return None   # in case the client overrides Exit

    self.command = self.cmd_dict[self.command_string]

    # "rargs" = remaining (unparsed) arguments
    # "largs" = already parsed, "left" of the read head
    self.rargs = argv[1:]
    self.largs = []

    # let the command object do the parsing
    self.command.ParseArguments()

    if self.command.parse_errors:
      # there were errors, output the usage string and exit
      self.err.write(self.command.GetUsageString()+"\n\n")
      self.err.write("\n".join(self.command.parse_errors))
      self.err.write("\n\n")

      self.Exit()

    elif execute and self.command.impl:
      self.command.impl(self.command)

    return self.command

  def __getitem__(self, key):
    return self.cmd_dict[key]

  def __iter__(self):
    return self.cmd_dict.__iter__()


def ValidateHelpCommand(command):
  """Checks to make sure an argument to 'help' is a valid command."""
  if 'command' in command and command['command'] not in command.cmdline:
    raise ParseError("'%s': unknown command" % command['command'])


def DoHelpCommand(command):
  """Executed when the command is 'help'."""
  out = command.cmdline.out
  width = command['--width']

  if 'command' not in command:
    out.write(command.GetUsageString())
    out.write("\n\n")

    indent = 5
    gutter = 2

    command_width = (
      max([len(cmd.names[0]) for cmd in command.cmdline.commands]) + gutter)

    for cmd in command.cmdline.commands:
      cmd_name = cmd.names[0]

      initial_indent = (" "*indent + cmd_name + " "*
                        (command_width+gutter-len(cmd_name)))
      subsequent_indent = " "*(indent+command_width+gutter)

      out.write(textwrap.fill(cmd.helptext, width,
                              initial_indent=initial_indent,
                              subsequent_indent=subsequent_indent))
      out.write("\n")

    out.write("\n")

  else:
    help_cmd = command.cmdline[command['command']]

    out.write(textwrap.fill(help_cmd.helptext, width))
    out.write("\n\n")
    out.write(help_cmd.GetUsageString(width=width))
    out.write("\n\n")
    out.write(help_cmd.GetHelpString(width=width))
    out.write("\n")

    command.cmdline.Exit()


def main():
  # If we're invoked rather than imported, run some tests
  cmdline = CommandLine()

  # Since we're testing, override Exit()
  def TestExit():
    pass
  cmdline.Exit = TestExit

  # Actually, while we're at it, let's override error output too
  cmdline.err = open(os.path.devnull, "w")

  test = cmdline.AddCommand(["test", "testa", "testb"], "test command")
  test.AddArgument(["-i", "--int", "--integer", "--optint", "--optionalint"],
                   "optional integer parameter", type='int')
  test.AddArgument("--reqint", "required integer parameter", type='int',
                   required=True)
  test.AddArgument("pos1", "required positional argument", positional=True,
                   required=True)
  test.AddArgument("pos2", "optional positional argument", positional=True)
  test.AddArgument("pos3", "another optional positional arg",
                   positional=True)

  # mutually dependent arguments
  test.AddArgument("--mutdep1", "mutually dependent parameter 1")
  test.AddArgument("--mutdep2", "mutually dependent parameter 2")
  test.AddArgument("--mutdep3", "mutually dependent parameter 3")
  test.AddMutualDependency(["--mutdep1", "--mutdep2", "--mutdep3"])

  # mutually exclusive arguments
  test.AddArgument("--mutex1", "mutually exclusive parameter 1")
  test.AddArgument("--mutex2", "mutually exclusive parameter 2")
  test.AddArgument("--mutex3", "mutually exclusive parameter 3")
  test.AddMutualExclusion(["--mutex1", "--mutex2", "--mutex3"])

  # dependent argument
  test.AddArgument("--dependent", "dependent argument")
  test.AddDependency("--dependent", "--int")

  # other argument types
  test.AddArgument("--file", "filename argument", type='readfile')
  test.AddArgument("--coords", "coordinate argument", type='coords')
  test.AddArgument("--flag", "flag argument", type='flag')

  test.AddArgument("--req1", "part of a required group", type='flag')
  test.AddArgument("--req2", "part 2 of a required group", type='flag')

  test.AddRequiredGroup(["--req1", "--req2"])

  # a few failure cases
  exception_cases = """
    test.AddArgument("failpos", "can't have req'd pos arg after opt",
       positional=True, required=True)
+++
    test.AddArgument("--int", "this argument already exists")
+++
    test.AddDependency("--int", "--doesntexist")
+++
    test.AddMutualDependency(["--doesntexist", "--mutdep2"])
+++
    test.AddMutualExclusion(["--doesntexist", "--mutex2"])
+++
    test.AddArgument("--reqflag", "required flag", required=True, type='flag')
+++
    test.AddRequiredGroup(["--req1", "--doesntexist"])
"""
  for exception_case in exception_cases.split("+++"):
    try:
      exception_case = exception_case.strip()
      exec exception_case     # yes, I'm using exec, it's just for a test.
    except ValueError:
      # this is expected
      pass
    except KeyError:
      # ...and so is this
      pass
    else:
      print ("FAILURE: expected an exception for '%s'"
             " and didn't get it" % exception_case)

  # Let's do some parsing! first, the minimal success line:
  MIN = "test --reqint 123 param1 --req1 "

  # tuples of (command line, expected error count)
  test_lines = [
    ("test --int 3 foo --req1", 1),   # missing required named parameter
    ("test --reqint 3 --req1", 1),    # missing required positional parameter
    (MIN, 0),                         # success!
    ("test param1 --reqint 123 --req1", 0),  # success, order shouldn't matter
    ("test param1 --reqint 123 --req2", 0),  # success, any of required group ok
    (MIN+"param2", 0),                # another positional parameter is okay
    (MIN+"param2 param3", 0),         # and so are three
    (MIN+"param2 param3 param4", 1),  # but four are just too many
    (MIN+"--int", 1),                 # where's the value?
    (MIN+"--int 456", 0),             # this is fine
    (MIN+"--int456", 0),              # as is this
    (MIN+"--int:456", 0),             # and this
    (MIN+"--int=456", 0),             # and this
    (MIN+"--file c:\\windows\\system32\\kernel32.dll", 0),  # yup
    (MIN+"--file c:\\thisdoesntexist", 1),           # nope
    (MIN+"--mutdep1 a", 2),                          # no!
    (MIN+"--mutdep2 b", 2),                          # also no!
    (MIN+"--mutdep3 c", 2),                          # dream on!
    (MIN+"--mutdep1 a --mutdep2 b", 2),              # almost!
    (MIN+"--mutdep1 a --mutdep2 b --mutdep3 c", 0),  # yes
    (MIN+"--mutex1 a", 0),                           # yes
    (MIN+"--mutex2 b", 0),                           # yes
    (MIN+"--mutex3 c", 0),                           # fine
    (MIN+"--mutex1 a --mutex2 b", 1),                # not fine
    (MIN+"--mutex1 a --mutex2 b --mutex3 c", 3),     # even worse
    (MIN+"--dependent 1", 1),                        # no
    (MIN+"--dependent 1 --int 2", 0),                # ok
    (MIN+"--int abc", 1),                            # bad type
    (MIN+"--coords abc", 1),                         # also bad
    (MIN+"--coords (abc)", 1),                       # getting warmer
    (MIN+"--coords (abc,def)", 1),                   # missing something
    (MIN+"--coords (123)", 1),                       # ooh, so close
    (MIN+"--coords (123,def)", 1),                   # just a little farther
    (MIN+"--coords (123,456)", 0),                   # finally!
    ("test --int 123 --reqint=456 foo bar --coords(42,88) baz --req1", 0)
    ]

  badtests = 0

  for (test, expected_failures) in test_lines:
    cmdline.ParseCommandLine([x.strip() for x in test.strip().split(" ")])

    if not len(cmdline.command.parse_errors) == expected_failures:
      print "FAILED:\n  issued: '%s'\n  expected: %d\n  received: %d\n\n" % (
        test, expected_failures, len(cmdline.command.parse_errors))
      badtests += 1

  print "%d failed out of %d tests" % (badtests, len(test_lines))

  cmdline.ParseCommandLine(["help", "test"])


if __name__ == "__main__":
  sys.exit(main())
