# 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/>.
"""Command line interface helper classes.

It provides some default commands, a help system, a default readline
configuration with completion and persistent history.

Example::

    class BookShell(CLIHelper):

        def __init__(self):
            # quit and help are builtins
            # CMD_MAP keys are commands, values are topics
            self.CMD_MAP['pionce'] = _("Sommeil")
            self.CMD_MAP['ronfle'] = _("Sommeil")
            CLIHelper.__init__(self)

        help_do_pionce = ("pionce", "pionce duree", _("met ton corps en veille"))
        def do_pionce(self):
            print 'nap is good'

        help_do_ronfle = ("ronfle", "ronfle volume", _("met les autres en veille"))
        def do_ronfle(self):
            print 'fuuuuuuuuuuuu rhhhhhrhrhrrh'

    cl = BookShell()
"""

__docformat__ = "restructuredtext en"

from six.moves import builtins, input

if not hasattr(builtins, '_'):
    builtins._ = str


def init_readline(complete_method, histfile=None):
    """Init the readline library if available."""
    try:
        import readline
        readline.parse_and_bind("tab: complete")
        readline.set_completer(complete_method)
        string = readline.get_completer_delims().replace(':', '')
        readline.set_completer_delims(string)
        if histfile is not None:
            try:
                readline.read_history_file(histfile)
            except IOError:
                pass
            import atexit
            atexit.register(readline.write_history_file, histfile)
    except:
        print 'readline is not available :-('


class Completer :
    """Readline completer."""

    def __init__(self, commands):
        self.list = commands

    def complete(self, text, state):
        """Hook called by readline when <tab> is pressed."""
        n = len(text)
        matches = []
        for cmd in self.list :
            if cmd[:n] == text :
                matches.append(cmd)
        try:
            return matches[state]
        except IndexError:
            return None


class CLIHelper:
    """An abstract command line interface client which recognize commands
    and provide an help system.
    """

    CMD_MAP = {'help': _("Others"),
               'quit': _("Others"),
               }
    CMD_PREFIX = ''

    def __init__(self, histfile=None) :
        self._topics = {}
        self.commands = None
        self._completer = Completer(self._register_commands())
        init_readline(self._completer.complete, histfile)

    def run(self):
        """loop on user input, exit on EOF"""
        while True:
            try:
                line = input('>>> ')
            except EOFError:
                print
                break
            s_line = line.strip()
            if not s_line:
                continue
            args = s_line.split()
            if args[0] in self.commands:
                try:
                    cmd = 'do_%s' % self.commands[args[0]]
                    getattr(self, cmd)(*args[1:])
                except EOFError:
                    break
                except:
                    import traceback
                    traceback.print_exc()
            else:
                try:
                    self.handle_line(s_line)
                except:
                    import traceback
                    traceback.print_exc()

    def handle_line(self, stripped_line):
        """Method to overload in the concrete class (should handle
        lines which are not commands).
        """
        raise NotImplementedError()


    # private methods #########################################################

    def _register_commands(self):
        """ register available commands method and return the list of
        commands name
        """
        self.commands = {}
        self._command_help = {}
        commands = [attr[3:] for attr in dir(self) if attr[:3] == 'do_']
        for command in commands:
            topic = self.CMD_MAP[command]
            help_method = getattr(self, 'help_do_%s' % command)
            self._topics.setdefault(topic, []).append(help_method)
            self.commands[self.CMD_PREFIX + command] = command
            self._command_help[command] = help_method
        return self.commands.keys()

    def _print_help(self, cmd, syntax, explanation):
        print _('Command %s') % cmd
        print _('Syntax: %s') % syntax
        print '\t', explanation
        print


    # predefined commands #####################################################

    def do_help(self, command=None) :
        """base input of the help system"""
        if command in self._command_help:
            self._print_help(*self._command_help[command])
        elif command is None or command not in self._topics:
            print _("Use help <topic> or help <command>.")
            print _("Available topics are:")
            topics = sorted(self._topics.keys())
            for topic in topics:
                print '\t', topic
            print
            print _("Available commands are:")
            commands = self.commands.keys()
            commands.sort()
            for command in commands:
                print '\t', command[len(self.CMD_PREFIX):]

        else:
            print _('Available commands about %s:') % command
            print
            for command_help_method in self._topics[command]:
                try:
                    if callable(command_help_method):
                        self._print_help(*command_help_method())
                    else:
                        self._print_help(*command_help_method)
                except:
                    import traceback
                    traceback.print_exc()
                    print 'ERROR in help method %s'% (
                        command_help_method.__name__)

    help_do_help = ("help", "help [topic|command]",
                    _("print help message for the given topic/command or \
available topics when no argument"))

    def do_quit(self):
        """quit the CLI"""
        raise EOFError()

    def help_do_quit(self):
        return ("quit", "quit", _("quit the application"))
