import imp
import importlib
import os
import textwrap

# Defines a table structure for printing to the terminal.
class Table:
    # Takes a list of column names
    def __init__(self, columns):
        self.Padding = []
        self.Table = [columns]
        for col in columns:
            self.Padding.append(len(col))

    # Takes a row entry for every column
    def add_row(self, row):
        # Number of entries and Columns do not match
        if len(row) != len(self.Table[0]):
            return

        # Adjust padding for each column
        for index in range(len(row)):
            if len(row[index]) > self.Padding[index]:
                self.Padding[index] = len(row[index])

        self.Table.append(row)

    def to_string(self):
        table_string = ""
        for row in self.Table:
            for index in range(len(row)):
                entry = row[index]
                table_string += "%s%s" % \
                        (entry, " " * (self.Padding[index] - len(entry) + 2 ))
            table_string += "\n"

        return table_string

def import_modules(package_paths, module_type):
    """
    Looks for python packages under `package_paths` and imports
    them as modules. Returns a dictionary of the basename of the
    `package_paths` to the imported modules.
    """
    modules = {}
    for package_path in package_paths:
        # We put the imported module into the namespace of
        # "mesos.<module_type>.<>" to keep it from cluttering up
        # the import namespace elsewhere.
        package_name = os.path.basename(package_path)
        package_dir = os.path.dirname(package_path)
        module_name = "mesos." + module_type + "." + package_name
        try:
            module = importlib.import_module(module_name)
        except:
            (file, filename, data) = imp.find_module(package_name, \
                                                        [package_dir])
            module = imp.load_module(module_name, file, filename, data)
        modules[package_name] = module

    return modules


def get_module(modules, import_path):
    """
    Given a modules dictionary returned by `import_modules()`,
    return a reference to the module at `import_path` relative
    to the base module. For example, get_module(modules, "example.stuff")
    will return a reference to the "stuff" module inside the
    imported "example" plugin.
    """
    import_path = import_path.split('.')
    module = modules[import_path[0]]
    if len(import_path) > 1:
        module = getattr(module, ".".join(import_path[1:]))
    return module


def completions(comp_words, current_word, argv):
    comp_words += ["-h", "--help", "--version"]

    if len(argv) == 0:
        return comp_words

    if len(argv) == 1:
        if argv[0] not in comp_words and current_word:
            return comp_words

        if argv[0] in comp_words and current_word:
            return comp_words

        if argv[0] not in comp_words and not current_word:
            return []

        if argv[0] in comp_words and not current_word:
            return None

    if len(argv) > 1 and argv[0] not in comp_words:
        return []

    if len(argv) > 1 and argv[0] in comp_words:
        return None

    raise Exception("Unreachable")

def format_commands_help(cmds):
    longest_cmd_name = max(cmds.keys(), key=len)

    help_string = ""
    for cmd in sorted(cmds.keys()):
        # For mesos, the `cmds` is a single-level dictionary with `short_help`
        # as the values.  For plugins, the `cmds` is a two-level dictionary,
        # where `short_help` is a field in each sub-dictionary.
        short_help = cmds[cmd]
        if isinstance(short_help, dict):
            short_help = short_help["short_help"]

        num_spaces = len(longest_cmd_name) - len(cmd) + 2
        help_string += "  %s%s%s\n" % (cmd, " " * num_spaces, short_help)

    return help_string

def format_subcommands_help(cmd):
    arguments = " ".join(cmd["arguments"])
    short_help = cmd["short_help"]
    long_help = textwrap.dedent(cmd["long_help"].rstrip())
    long_help = "  " + "\n  ".join(long_help.split('\n'))
    flags = cmd["flags"]
    flags["-h --help"] = "Show this screen."
    flag_string = ""

    if len(flags.keys()) != 0:
        longest_flag_name = max(flags.keys(), key=len)
        for flag in sorted(flags.keys()):
            num_spaces = len(longest_flag_name) - len(flag) + 2
            flag_string += "  %s%s%s\n" % (flag, " " * num_spaces, flags[flag])

    return (arguments, short_help, long_help, flag_string)
