# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
#
# logilab-common is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option) any
# later version.
#
# logilab-common is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with logilab-common.  If not, see <http://www.gnu.org/licenses/>.
"""Helper functions to support command line tools providing more than
one command.

e.g called as "tool command [options] args..." where <options> and <args> are
command'specific
"""

from __future__ import print_function

__docformat__ = "restructuredtext en"

import sys
import logging
from os.path import basename

from logilab.common.configuration import Configuration
from logilab.common.logging_ext import init_log, get_threshold
from logilab.common.deprecation import deprecated


class BadCommandUsage(Exception):
    """Raised when an unknown command is used or when a command is not
    correctly used (bad options, too much / missing arguments...).

    Trigger display of command usage.
    """

class CommandError(Exception):
    """Raised when a command can't be processed and we want to display it and
    exit, without traceback nor usage displayed.
    """


# command line access point ####################################################

class CommandLine(dict):
    """Usage:

    >>> LDI = cli.CommandLine('ldi', doc='Logilab debian installer',
                              version=version, rcfile=RCFILE)
    >>> LDI.register(MyCommandClass)
    >>> LDI.register(MyOtherCommandClass)
    >>> LDI.run(sys.argv[1:])

    Arguments:

    * `pgm`, the program name, default to `basename(sys.argv[0])`

    * `doc`, a short description of the command line tool

    * `copyright`, additional doc string that will be appended to the generated
      doc

    * `version`, version number of string of the tool. If specified, global
      --version option will be available.

    * `rcfile`, path to a configuration file. If specified, global --C/--rc-file
      option will be available?  self.rcfile = rcfile

    * `logger`, logger to propagate to commands, default to
      `logging.getLogger(self.pgm))`
    """
    def __init__(self, pgm=None, doc=None, copyright=None, version=None,
                 rcfile=None, logthreshold=logging.ERROR,
                 check_duplicated_command=True):
        if pgm is None:
            pgm = basename(sys.argv[0])
        self.pgm = pgm
        self.doc = doc
        self.copyright = copyright
        self.version = version
        self.rcfile = rcfile
        self.logger = None
        self.logthreshold = logthreshold
        self.check_duplicated_command = check_duplicated_command

    def register(self, cls, force=False):
        """register the given :class:`Command` subclass"""
        assert not self.check_duplicated_command or force or not cls.name in self, \
               'a command %s is already defined' % cls.name
        self[cls.name] = cls
        return cls

    def run(self, args):
        """main command line access point:
        * init logging
        * handle global options (-h/--help, --version, -C/--rc-file)
        * check command
        * run command

        Terminate by :exc:`SystemExit`
        """
        init_log(debug=True, # so that we use StreamHandler
                 logthreshold=self.logthreshold,
                 logformat='%(levelname)s: %(message)s')
        try:
            arg = args.pop(0)
        except IndexError:
            self.usage_and_exit(1)
        if arg in ('-h', '--help'):
            self.usage_and_exit(0)
        if self.version is not None and arg in ('--version'):
            print(self.version)
            sys.exit(0)
        rcfile = self.rcfile
        if rcfile is not None and arg in ('-C', '--rc-file'):
            try:
                rcfile = args.pop(0)
                arg = args.pop(0)
            except IndexError:
                self.usage_and_exit(1)
        try:
            command = self.get_command(arg)
        except KeyError:
            print('ERROR: no %s command' % arg)
            print()
            self.usage_and_exit(1)
        try:
            sys.exit(command.main_run(args, rcfile))
        except KeyboardInterrupt as exc:
            print('Interrupted', end=' ')
            if str(exc):
                print(': %s' % exc, end=' ')
            print()
            sys.exit(4)
        except BadCommandUsage as err:
            print('ERROR:', err)
            print()
            print(command.help())
            sys.exit(1)

    def create_logger(self, handler, logthreshold=None):
        logger = logging.Logger(self.pgm)
        logger.handlers = [handler]
        if logthreshold is None:
            logthreshold = get_threshold(self.logthreshold)
        logger.setLevel(logthreshold)
        return logger

    def get_command(self, cmd, logger=None):
        if logger is None:
            logger = self.logger
        if logger is None:
            logger = self.logger = logging.getLogger(self.pgm)
            logger.setLevel(get_threshold(self.logthreshold))
        return self[cmd](logger)

    def usage(self):
        """display usage for the main program (i.e. when no command supplied)
        and exit
        """
        print('usage:', self.pgm, end=' ')
        if self.rcfile:
            print('[--rc-file=<configuration file>]', end=' ')
        print('<command> [options] <command argument>...')
        if self.doc:
            print('\n%s' % self.doc)
        print('''
Type "%(pgm)s <command> --help" for more information about a specific
command. Available commands are :\n''' % self.__dict__)
        max_len = max([len(cmd) for cmd in self])
        padding = ' ' * max_len
        for cmdname, cmd in sorted(self.items()):
            if not cmd.hidden:
                print(' ', (cmdname + padding)[:max_len], cmd.short_description())
        if self.rcfile:
            print('''
Use --rc-file=<configuration file> / -C <configuration file> before the command
to specify a configuration file. Default to %s.
''' % self.rcfile)
        print('''%(pgm)s -h/--help
      display this usage information and exit''' % self.__dict__)
        if self.version:
            print('''%(pgm)s -v/--version
      display version configuration and exit''' % self.__dict__)
        if self.copyright:
            print('\n', self.copyright)

    def usage_and_exit(self, status):
        self.usage()
        sys.exit(status)


# base command classes #########################################################

class Command(Configuration):
    """Base class for command line commands.

    Class attributes:

    * `name`, the name of the command

    * `min_args`, minimum number of arguments, None if unspecified

    * `max_args`, maximum number of arguments, None if unspecified

    * `arguments`, string describing arguments, used in command usage

    * `hidden`, boolean flag telling if the command should be hidden, e.g. does
      not appear in help's commands list

    * `options`, options list, as allowed by :mod:configuration
    """

    arguments = ''
    name = ''
    # hidden from help ?
    hidden = False
    # max/min args, None meaning unspecified
    min_args = None
    max_args = None

    @classmethod
    def description(cls):
        return cls.__doc__.replace('    ', '')

    @classmethod
    def short_description(cls):
        return cls.description().split('.')[0]

    def __init__(self, logger):
        usage = '%%prog %s %s\n\n%s' % (self.name, self.arguments,
                                        self.description())
        Configuration.__init__(self, usage=usage)
        self.logger = logger

    def check_args(self, args):
        """check command's arguments are provided"""
        if self.min_args is not None and len(args) < self.min_args:
            raise BadCommandUsage('missing argument')
        if self.max_args is not None and len(args) > self.max_args:
            raise BadCommandUsage('too many arguments')

    def main_run(self, args, rcfile=None):
        """Run the command and return status 0 if everything went fine.

        If :exc:`CommandError` is raised by the underlying command, simply log
        the error and return status 2.

        Any other exceptions, including :exc:`BadCommandUsage` will be
        propagated.
        """
        if rcfile:
            self.load_file_configuration(rcfile)
        args = self.load_command_line_configuration(args)
        try:
            self.check_args(args)
            self.run(args)
        except CommandError as err:
            self.logger.error(err)
            return 2
        return 0

    def run(self, args):
        """run the command with its specific arguments"""
        raise NotImplementedError()


class ListCommandsCommand(Command):
    """list available commands, useful for bash completion."""
    name = 'listcommands'
    arguments = '[command]'
    hidden = True

    def run(self, args):
        """run the command with its specific arguments"""
        if args:
            command = args.pop()
            cmd = _COMMANDS[command]
            for optname, optdict in cmd.options:
                print('--help')
                print('--' + optname)
        else:
            commands = sorted(_COMMANDS.keys())
            for command in commands:
                cmd = _COMMANDS[command]
                if not cmd.hidden:
                    print(command)


# deprecated stuff #############################################################

_COMMANDS = CommandLine()

DEFAULT_COPYRIGHT = '''\
Copyright (c) 2004-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
http://www.logilab.fr/ -- mailto:contact@logilab.fr'''

@deprecated('use cls.register(cli)')
def register_commands(commands):
    """register existing commands"""
    for command_klass in commands:
        _COMMANDS.register(command_klass)

@deprecated('use args.pop(0)')
def main_run(args, doc=None, copyright=None, version=None):
    """command line tool: run command specified by argument list (without the
    program name). Raise SystemExit with status 0 if everything went fine.

    >>> main_run(sys.argv[1:])
    """
    _COMMANDS.doc = doc
    _COMMANDS.copyright = copyright
    _COMMANDS.version = version
    _COMMANDS.run(args)

@deprecated('use args.pop(0)')
def pop_arg(args_list, expected_size_after=None, msg="Missing argument"):
    """helper function to get and check command line arguments"""
    try:
        value = args_list.pop(0)
    except IndexError:
        raise BadCommandUsage(msg)
    if expected_size_after is not None and len(args_list) > expected_size_after:
        raise BadCommandUsage('too many arguments')
    return value

