""" CommandLine - Get and parse command line options

    NOTE: This still is very much work in progress !!!

    Different version are likely to be incompatible.

    TODO:

    * Incorporate the changes made by (see Inbox)
    * Add number range option using srange()

"""

__copyright__ = """\
Copyright (c), 1997-2006, Marc-Andre Lemburg (mal@lemburg.com)
Copyright (c), 2000-2006, eGenix.com Software GmbH (info@egenix.com)
See the documentation for further information on copyrights,
or contact the author. All Rights Reserved.
"""

__version__ = '1.2'

import sys, getopt, string, glob, os, re, exceptions, traceback

### Helpers

def _getopt_flags(options):

    """ Convert the option list to a getopt flag string and long opt
        list

    """
    s = []
    l = []
    for o in options:
        if o.prefix == '-':
            # short option
            s.append(o.name)
            if o.takes_argument:
                s.append(':')
        else:
            # long option
            if o.takes_argument:
                l.append(o.name+'=')
            else:
                l.append(o.name)
    return string.join(s,''),l

def invisible_input(prompt='>>> '):

    """ Get raw input from a terminal without echoing the characters to
        the terminal, e.g. for password queries.

    """
    import getpass
    entry = getpass.getpass(prompt)
    if entry is None:
        raise KeyboardInterrupt
    return entry

def fileopen(name, mode='wb', encoding=None):

    """ Open a file using mode.

        Default mode is 'wb' meaning to open the file for writing in
        binary mode. If encoding is given, I/O to and from the file is
        transparently encoded using the given encoding.

        Files opened for writing are chmod()ed to 0600.

    """
    if name == 'stdout':
        return sys.stdout
    elif name == 'stderr':
        return sys.stderr
    elif name == 'stdin':
        return sys.stdin
    else:
        if encoding is not None:
            import codecs
            f = codecs.open(name, mode, encoding)
        else:
            f = open(name, mode)
        if 'w' in mode:
            os.chmod(name, 0600)
        return f

def option_dict(options):

    """ Return a dictionary mapping option names to Option instances.
    """
    d = {}
    for option in options:
        d[option.name] = option
    return d

# Alias
getpasswd = invisible_input

_integerRE = re.compile('\s*(-?\d+)\s*$')
_integerRangeRE = re.compile('\s*(-?\d+)\s*-\s*(-?\d+)\s*$')

def srange(s,

           split=string.split,integer=_integerRE,
           integerRange=_integerRangeRE):

    """ Converts a textual representation of integer numbers and ranges
        to a Python list.

        Supported formats: 2,3,4,2-10,-1 - -3, 5 - -2

        Values are appended to the created list in the order specified
        in the string.

    """
    l = []
    append = l.append
    for entry in split(s,','):
        m = integer.match(entry)
        if m:
            append(int(m.groups()[0]))
            continue
        m = integerRange.match(entry)
        if m:
            start,end = map(int,m.groups())
            l[len(l):] = range(start,end+1)
    return l

def abspath(path,

            expandvars=os.path.expandvars,expanduser=os.path.expanduser,
            join=os.path.join,getcwd=os.getcwd):

    """ Return the corresponding absolute path for path.

        path is expanded in the usual shell ways before
        joining it with the current working directory.

    """
    try:
        path = expandvars(path)
    except AttributeError:
        pass
    try:
        path = expanduser(path)
    except AttributeError:
        pass
    return join(getcwd(), path)

### Option classes

class Option:

    """ Option base class. Takes no argument.

    """
    default = None
    helptext = ''
    prefix = '-'
    takes_argument = 0
    has_default = 0
    tab = 15

    def __init__(self,name,help=None):

        if not name[:1] == '-':
            raise TypeError,'option names must start with "-"'
        if name[1:2] == '-':
            self.prefix = '--'
            self.name = name[2:]
        else:
            self.name = name[1:]
        if help:
            self.help = help

    def __str__(self):

        o = self
        name = o.prefix + o.name
        if o.takes_argument:
            name = name + ' arg'
        if len(name) > self.tab:
            name = name + '\n' + ' ' * (self.tab + 1 + len(o.prefix))
        else:
            name = '%-*s ' % (self.tab, name)
        description = o.help
        if o.has_default:
            description = description + ' (%s)' % o.default
        return '%s %s' % (name, description)

class ArgumentOption(Option):

    """ Option that takes an argument.

        An optional default argument can be given.

    """
    def __init__(self,name,help=None,default=None):

        # Basemethod
        Option.__init__(self,name,help)

        if default is not None:
            self.default = default
            self.has_default = 1
        self.takes_argument = 1

class SwitchOption(Option):

    """ Options that can be on or off. Has an optional default value.

    """
    def __init__(self,name,help=None,default=None):

        # Basemethod
        Option.__init__(self,name,help)

        if default is not None:
            self.default = default
            self.has_default = 1

### Application baseclass

class Application:

    """ Command line application interface with builtin argument
        parsing.

    """
    # Options the program accepts (Option instances)
    options = []

    # Standard settings; these are appended to options in __init__
    preset_options = [SwitchOption('-v',
                                   'generate verbose output'),
                      SwitchOption('-h',
                                   'show this help text'),
                      SwitchOption('--help',
                                   'show this help text'),
                      SwitchOption('--debug',
                                   'enable debugging'),
                      SwitchOption('--copyright',
                                   'show copyright'),
                      SwitchOption('--examples',
                                   'show examples of usage')]

    # The help layout looks like this:
    # [header]   - defaults to ''
    #
    # [synopsis] - formatted as '<self.name> %s' % self.synopsis
    #
    # options:
    # [options]  - formatted from self.options
    #
    # [version]  - formatted as 'Version:\n %s' % self.version, if given
    #
    # [about]    - defaults to ''
    #
    # Note: all fields that do not behave as template are formatted
    #       using the instances dictionary as substitution namespace,
    #       e.g. %(name)s will be replaced by the applications name.
    #

    # Header (default to program name)
    header = ''

    # Name (defaults to program name)
    name = ''

    # Synopsis (%(name)s is replaced by the program name)
    synopsis = '%(name)s [option] files...'

    # Version (optional)
    version = ''

    # General information printed after the possible options (optional)
    about = ''

    # Examples of usage to show when the --examples option is given (optional)
    examples = ''

    # Copyright to show
    copyright = __copyright__

    # Apply file globbing ?
    globbing = 1

    # Generate debug output ?
    debug = 0

    # Generate verbose output ?
    verbose = 0

    # Internal errors to catch
    InternalError = exceptions.Exception

    # Instance variables:
    values = None       # Dictionary of passed options (or default values)
                        # indexed by the options name, e.g. '-h'
    files = None        # List of passed filenames
    optionlist = None   # List of passed options

    def __init__(self,argv=None):

        # Setup application specs
        if argv is None:
            argv = sys.argv
        self.filename = os.path.split(argv[0])[1]
        if not self.name:
            self.name = os.path.split(self.filename)[1]
        else:
            self.name = self.name
        if not self.header:
            self.header = self.name
        else:
            self.header = self.header

        # Init .arguments list
        self.arguments = argv[1:]

        # Setup Option mapping
        self.option_map = option_dict(self.options)

        # Append preset options
        for option in self.preset_options:
            if not self.option_map.has_key(option.name):
                self.add_option(option)

        # Init .files list
        self.files = []

        # Start Application
        try:
            # Process startup
            rc = self.startup()
            if rc is not None:
                raise SystemExit,rc

            # Parse command line
            rc = self.parse()
            if rc is not None:
                raise SystemExit,rc

            # Start application
            rc = self.main()
            if rc is None:
                rc = 0

        except SystemExit,rc:
            pass

        except KeyboardInterrupt:
            print
            print '* User Break'
            print
            rc = 1

        except self.InternalError:
            print
            print '* Internal Error (use --debug to display the traceback)'
            if self.debug:
                print
                traceback.print_exc(20, sys.stdout)
            elif self.verbose:
                print '  %s: %s' % sys.exc_info()[:2]
            print
            rc = 1

        raise SystemExit,rc

    def add_option(self, option):

        """ Add a new Option instance to the Application dynamically.

            Note that this has to be done *before* .parse() is being
            executed.

        """
        self.options.append(option)
        self.option_map[option.name] = option

    def startup(self):

        """ Set user defined instance variables.

            If this method returns anything other than None, the
            process is terminated with the return value as exit code.

        """
        return None

    def exit(self, rc=0):

        """ Exit the program.

            rc is used as exit code and passed back to the calling
            program. It defaults to 0 which usually means: OK.

        """
        raise SystemExit, rc

    def parse(self):

        """ Parse the command line and fill in self.values and self.files.

            After having parsed the options, the remaining command line
            arguments are interpreted as files and passed to .handle_files()
            for processing.

            As final step the option handlers are called in the order
            of the options given on the command line.

        """
        # Parse arguments
        self.values = values = {}
        for o in self.options:
            if o.has_default:
                values[o.prefix+o.name] = o.default
            else:
                values[o.prefix+o.name] = 0
        flags,lflags = _getopt_flags(self.options)
        try:
            optlist,files = getopt.getopt(self.arguments,flags,lflags)
            if self.globbing:
                l = []
                for f in files:
                    gf = glob.glob(f)
                    if not gf:
                        l.append(f)
                    else:
                        l[len(l):] = gf
                files = l
            self.optionlist = optlist
            self.files = files + self.files
        except getopt.error,why:
            self.help(why)
            sys.exit(1)

        # Call file handler
        rc = self.handle_files(self.files)
        if rc is not None:
            sys.exit(rc)

        # Call option handlers
        for optionname, value in optlist:

            # Try to convert value to integer
            try:
                value = string.atoi(value)
            except ValueError:
                pass

            # Find handler and call it (or count the number of option
            # instances on the command line)
            handlername = 'handle' + string.replace(optionname, '-', '_')
            try:
                handler = getattr(self, handlername)
            except AttributeError:
                if value == '':
                    # count the number of occurrences
                    if values.has_key(optionname):
                        values[optionname] = values[optionname] + 1
                    else:
                        values[optionname] = 1
                else:
                    values[optionname] = value
            else:
                rc = handler(value)
                if rc is not None:
                    raise SystemExit, rc

        # Apply final file check (for backward compatibility)
        rc = self.check_files(self.files)
        if rc is not None:
            sys.exit(rc)

    def check_files(self,filelist):

        """ Apply some user defined checks on the files given in filelist.

            This may modify filelist in place. A typical application
            is checking that at least n files are given.

            If this method returns anything other than None, the
            process is terminated with the return value as exit code.

        """
        return None

    def help(self,note=''):

        self.print_header()
        if self.synopsis:
            print 'Synopsis:'
            # To remain backward compatible:
            try:
                synopsis = self.synopsis % self.name
            except (NameError, KeyError, TypeError):
                synopsis = self.synopsis % self.__dict__
            print ' ' + synopsis
        print
        self.print_options()
        if self.version:
            print 'Version:'
            print ' %s' % self.version
            print
        if self.about:
            print string.strip(self.about % self.__dict__)
            print
        if note:
            print '-'*72
            print 'Note:',note
            print

    def notice(self,note):

        print '-'*72
        print 'Note:',note
        print '-'*72
        print

    def print_header(self):

        print '-'*72
        print self.header % self.__dict__
        print '-'*72
        print

    def print_options(self):

        options = self.options
        print 'Options and default settings:'
        if not options:
            print '  None'
            return
        long = filter(lambda x: x.prefix == '--', options)
        short = filter(lambda x: x.prefix == '-', options)
        items = short + long
        for o in options:
            print ' ',o
        print

    #
    # Example handlers:
    #
    # If a handler returns anything other than None, processing stops
    # and the return value is passed to sys.exit() as argument.
    #

    # File handler
    def handle_files(self,files):

        """ This may process the files list in place.
        """
        return None

    # Short option handler
    def handle_h(self,arg):

        self.help()
        return 0

    def handle_v(self, value):

        """ Turn on verbose output.
        """
        self.verbose = 1

    # Handlers for long options have two underscores in their name
    def handle__help(self,arg):

        self.help()
        return 0

    def handle__debug(self,arg):

        self.debug = 1
        # We don't want to catch internal errors:
        self.InternalError = None

    def handle__copyright(self,arg):

        self.print_header()
        print string.strip(self.copyright % self.__dict__)
        print
        return 0

    def handle__examples(self,arg):

        self.print_header()
        if self.examples:
            print 'Examples:'
            print
            print string.strip(self.examples % self.__dict__)
            print
        else:
            print 'No examples available.'
            print
        return 0

    def main(self):

        """ Override this method as program entry point.

            The return value is passed to sys.exit() as argument.  If
            it is None, 0 is assumed (meaning OK). Unhandled
            exceptions are reported with exit status code 1 (see
            __init__ for further details).

        """
        return None

# Alias
CommandLine = Application

def _test():

    class MyApplication(Application):
        header = 'Test Application'
        version = __version__
        options = [Option('-v','verbose')]

        def handle_v(self,arg):
            print 'VERBOSE, Yeah !'

    cmd = MyApplication()
    if not cmd.values['-h']:
        cmd.help()
    print 'files:',cmd.files
    print 'Bye...'

if __name__ == '__main__':
    _test()
