# DExTer : Debugging Experience Tester
# ~~~~~~   ~         ~~         ~   ~~
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""This is the main entry point.
It implements some functionality common to all subtools such as command line
parsing and running the unit-testing harnesses, before calling the reequested
subtool.
"""

import imp
import os
import sys

from dex.utils import PrettyOutput, Timer
from dex.utils import ExtArgParse as argparse
from dex.utils import get_root_directory
from dex.utils.Exceptions import Error, ToolArgumentError
from dex.utils.UnitTests import unit_tests_ok
from dex.utils.Version import version
from dex.utils import WorkingDirectory
from dex.utils.ReturnCode import ReturnCode


def _output_bug_report_message(context):
    """ In the event of a catastrophic failure, print bug report request to the
        user.
    """
    context.o.red(
        '\n\n'
        '<g>****************************************</>\n'
        '<b>****************************************</>\n'
        '****************************************\n'
        '**                                    **\n'
        '** <y>This is a bug in <a>DExTer</>.</>           **\n'
        '**                                    **\n'
        '**                  <y>Please report it.</> **\n'
        '**                                    **\n'
        '****************************************\n'
        '<b>****************************************</>\n'
        '<g>****************************************</>\n'
        '\n'
        '<b>system:</>\n'
        '<d>{}</>\n\n'
        '<b>version:</>\n'
        '<d>{}</>\n\n'
        '<b>args:</>\n'
        '<d>{}</>\n'
        '\n'.format(sys.platform, version('DExTer'),
                    [sys.executable] + sys.argv),
        stream=PrettyOutput.stderr)


def get_tools_directory():
    """ Returns directory path where DExTer tool imports can be
        found.
    """
    tools_directory = os.path.join(get_root_directory(), 'tools')
    assert os.path.isdir(tools_directory), tools_directory
    return tools_directory


def get_tool_names():
    """ Returns a list of expected DExTer Tools
    """
    return [
        'clang-opt-bisect', 'help', 'list-debuggers', 'no-tool-',
        'run-debugger-internal-', 'test', 'view'
    ]


def _set_auto_highlights(context):
    """Flag some strings for auto-highlighting.
    """
    context.o.auto_reds.extend([
        r'[Ee]rror\:',
        r'[Ee]xception\:',
        r'un(expected|recognized) argument',
    ])
    context.o.auto_yellows.extend([
        r'[Ww]arning\:',
        r'\(did you mean ',
        r'During handling of the above exception, another exception',
    ])


def _get_options_and_args(context):
    """ get the options and arguments from the commandline
    """
    parser = argparse.ExtArgumentParser(context, add_help=False)
    parser.add_argument('tool', default=None, nargs='?')
    options, args = parser.parse_known_args(sys.argv[1:])

    return options, args


def _get_tool_name(options):
    """ get the name of the dexter tool (if passed) specified on the command
        line, otherwise return 'no_tool_'.
    """
    tool_name = options.tool
    if tool_name is None:
        tool_name = 'no_tool_'
    else:
        _is_valid_tool_name(tool_name)
    return tool_name


def _is_valid_tool_name(tool_name):
    """ check tool name matches a tool directory within the dexter tools
        directory.
    """
    valid_tools = get_tool_names()
    if tool_name not in valid_tools:
        raise Error('invalid tool "{}" (choose from {})'.format(
            tool_name,
            ', '.join([t for t in valid_tools if not t.endswith('-')])))


def _import_tool_module(tool_name):
    """ Imports the python module at the tool directory specificed by
        tool_name.
    """
    # format tool argument to reflect tool directory form.
    tool_name = tool_name.replace('-', '_')

    tools_directory = get_tools_directory()
    module_info = imp.find_module(tool_name, [tools_directory])

    return imp.load_module(tool_name, *module_info)


def tool_main(context, tool, args):
    with Timer(tool.name):
        options, defaults = tool.parse_command_line(args)
        Timer.display = options.time_report
        Timer.indent = options.indent_timer_level
        Timer.fn = context.o.blue
        context.options = options
        context.version = version(tool.name)

        if options.version:
            context.o.green('{}\n'.format(context.version))
            return ReturnCode.OK

        if (options.unittest != 'off' and not unit_tests_ok(context)):
            raise Error('<d>unit test failures</>')

        if options.colortest:
            context.o.colortest()
            return ReturnCode.OK

        try:
            tool.handle_base_options(defaults)
        except ToolArgumentError as e:
            raise Error(e)

        dir_ = context.options.working_directory
        with WorkingDirectory(context, dir=dir_) as context.working_directory:
            return_code = tool.go()

        return return_code


class Context(object):
    """Context encapsulates globally useful objects and data; passed to many
    Dexter functions.
    """

    def __init__(self):
        self.o: PrettyOutput = None
        self.working_directory: str = None
        self.options: dict = None
        self.version: str = None
        self.root_directory: str = None


def main() -> ReturnCode:

    context = Context()

    with PrettyOutput() as context.o:
        try:
            context.root_directory = get_root_directory()
            # Flag some strings for auto-highlighting.
            _set_auto_highlights(context)
            options, args = _get_options_and_args(context)
            # raises 'Error' if command line tool is invalid.
            tool_name = _get_tool_name(options)
            module = _import_tool_module(tool_name)
            return tool_main(context, module.Tool(context), args)
        except Error as e:
            context.o.auto(
                '\nerror: {}\n'.format(str(e)), stream=PrettyOutput.stderr)
            try:
                if context.options.error_debug:
                    raise
            except AttributeError:
                pass
            return ReturnCode._ERROR
        except (KeyboardInterrupt, SystemExit):
            raise
        except:  # noqa
            _output_bug_report_message(context)
            raise
