"""DOC:TODO"""
# -*- coding: utf-8 -*-
# -- This file is part of the Apio project
# -- (C) 2016-2019 FPGAwars
# -- Author Jesús Arroyo
# -- Licence GPLv2

# --------------------------------------------
# -- Apio ENTRY POINT!!!
# --------------------------------------------


from os import listdir
from os.path import isfile
from sys import exit as sys_exit
import click

from apio import util


# -- The commands are python modules located in the commands folder
# -- Get the absolute path to all the commands
commands_folder = util.get_folder("commands")


# -- Auxiliary function used sfor reformating the Help string output
def find_commands_help(help_str, commands):
    """Extract the commands from the help string
    Return a list with the command + description
    """
    commands_help = []
    for line in list(help_str):
        for command in commands:
            if " " + command in line:
                if line in help_str:
                    help_str.remove(line)
                    commands_help.append(line)
    return commands_help


# -- Main Click Class
# -- It is extended for including methods for getting and listing the commands
class ApioCLI(click.MultiCommand):
    """DOC:TODO"""

    # -- Return  a list of all the available commands
    def list_commands(self, ctx):
        cmd_list = []

        # -- The supported command are python files located
        # -- in the commands folder
        # -- Except __init__.py
        for filename in listdir(commands_folder):
            if filename.startswith("__init__"):
                continue
            if filename.endswith(".py"):
                cmd_list.append(filename[:-3])

        cmd_list.sort()
        return cmd_list

    # -- Return the code function (cli) of the command name
    # -- This cli function is called whenever the name command
    # -- is issued
    # pylint: disable=arguments-differ
    def get_command(self, ctx, cmd_name):
        nnss = {}

        # -- Get the full filename of the python file for the command name
        filename = util.safe_join(commands_folder, cmd_name + ".py")

        # -- Return the cli function of the command
        if isfile(filename):
            with open(filename) as file:
                code = compile(file.read(), filename, "exec")
                eval(code, nnss, nnss)

        return nnss.get("cli")


@click.command(cls=ApioCLI, invoke_without_command=True)
@click.pass_context
@click.version_option()
def cli(ctx):

    # -- No command typed: show help
    if ctx.invoked_subcommand is None:

        # -- The help string is automatically generated by Click
        # -- It could be directly printed on the console but...
        _help = ctx.get_help()

        # -- Let's change the format so that the commands are divided
        # -- into three categories: Project, Setup and Utilitys
        _help = _help.split("\n")

        # -- Setup commands
        setup_help = find_commands_help(
            _help, ["drivers", "init", "install", "uninstall"]
        )

        # -- Utility commands
        util_help = find_commands_help(
            _help, ["boards", "config", "examples", "raw", "system", "upgrade"]
        )

        # -- Reformat the Help string
        _help = "\n".join(_help)
        _help = _help.replace("Commands:\n", "Project commands:\n")
        _help += "\n\nSetup commands:\n"
        _help += "\n".join(setup_help)
        _help += "\n\nUtility commands:\n"
        _help += "\n".join(util_help)
        _help += "\n"

        click.secho(_help)

    # -- If there is a command, it is executed when this function is finished
    # -- Debug: print the command invoked
    # print(f"{ctx.invoked_subcommand}")


# -- This is NOT used
if __name__ == "__main__":  # pragma: no cover
    sys_exit()
