# commands
#
# Copyright (C) 2011 Carlos Garcia Campos <carlosgc@gnome.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
from __future__ import absolute_import, division, print_function

import argparse

__all__ = [ 'register_command',
            'print_help',
            'run',
            'UnknownCommandError',
            'Command' ]

class UnknownCommandError(Exception):
    '''Unknown command'''

class Command:

    name = None
    usage_args = '[ options ... ]'
    description = None

    def __init__(self):
        self._parser = argparse.ArgumentParser(
            description = self.description,
            prog = 'poppler-regtest %s' % (self.name),
            usage = 'poppler-regtest %s %s' % (self.name, self.usage_args))

    def _get_args_parser(self):
        return self._parser

    def execute(self, args):
        ns = self._parser.parse_args(args)
        return self.run(vars(ns))

    def run(self, options):
        raise NotImplementedError

_commands = {}
def register_command(command_name, command_class):
    _commands[command_name] = command_class

def _get_command(command_name):
    if command_name not in _commands:
        try:
            __import__('commands.%s' % command_name)
        except ImportError:
            pass

    if command_name not in _commands:
        raise UnknownCommandError('Invalid %s command' % command_name)

    return _commands[command_name]

def run(args):
    command_class = _get_command(args[0])
    command = command_class()
    return command.execute(args[1:])

def print_help():
    import os
    thisdir = os.path.abspath(os.path.dirname(__file__))

    for fname in os.listdir(os.path.join(thisdir)):
        name, ext = os.path.splitext(fname)
        if not ext == '.py':
            continue
        try:
            __import__('commands.%s' % name)
        except ImportError:
            pass

    print("Commands are:")
    commands = sorted((x.name, x.description) for x in _commands.values())
    for name, description in commands:
        print("  %-15s %s" % (name, description))

    print()
    print("For more information run 'poppler-regtest --help-command <command>'")
