""" 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()

"""

from __future__ import print_function

__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, glob, os, re, 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 ''.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, 0o600)
        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,

           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 s.split(','):
        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 = BaseException

    # 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 option.name in self.option_map:
                self.add_option(option)

        # Init .files list
        self.files = []

        # Start Application
        rc = 0
        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 as rcException:
            rc = rcException
            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 as 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 = int(value)
            except ValueError:
                pass

            # Find handler and call it (or count the number of option
            # instances on the command line)
            handlername = 'handle' + optionname.replace('-', '_')
            try:
                handler = getattr(self, handlername)
            except AttributeError:
                if value == '':
                    # count the number of occurances
                    if optionname in values:
                        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:
            about = self.about % self.__dict__
            print(about.strip())
            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
        int = [x for x in options if x.prefix == '--']
        short = [x for x in options if x.prefix == '-']
        items = short + int
        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:
        class NoErrorToCatch(Exception): pass
        self.InternalError = NoErrorToCatch

    def handle__copyright(self,arg):

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

    def handle__examples(self,arg):

        self.print_header()
        if self.examples:
            print('Examples:')
            print()
            examples = self.examples % self.__dict__
            print(examples.strip())
            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()
