# 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
"""Discover potential/available debugger interfaces."""

from collections import OrderedDict
import os
import pickle
import subprocess
import sys
from tempfile import NamedTemporaryFile

from dex.command import get_command_infos
from dex.dextIR import DextIR
from dex.utils import get_root_directory, Timer
from dex.utils.Environment import is_native_windows
from dex.utils.Exceptions import ToolArgumentError
from dex.utils.Warning import warn
from dex.utils.Exceptions import DebuggerException

from dex.debugger.DebuggerControllers.DefaultController import DefaultController

from dex.debugger.dbgeng.dbgeng import DbgEng
from dex.debugger.lldb.LLDB import LLDB
from dex.debugger.visualstudio.VisualStudio2015 import VisualStudio2015
from dex.debugger.visualstudio.VisualStudio2017 import VisualStudio2017
from dex.debugger.visualstudio.VisualStudio2019 import VisualStudio2019


def _get_potential_debuggers():  # noqa
    """Return a dict of the supported debuggers.
    Returns:
        { name (str): debugger (class) }
    """
    return {
        DbgEng.get_option_name(): DbgEng,
        LLDB.get_option_name(): LLDB,
        VisualStudio2015.get_option_name(): VisualStudio2015,
        VisualStudio2017.get_option_name(): VisualStudio2017,
        VisualStudio2019.get_option_name(): VisualStudio2019
    }


def _warn_meaningless_option(context, option):
    if hasattr(context.options, 'list_debuggers'):
        return

    warn(context,
         'option <y>"{}"</> is meaningless with this debugger'.format(option),
         '--debugger={}'.format(context.options.debugger))


def add_debugger_tool_base_arguments(parser, defaults):
    defaults.lldb_executable = 'lldb.exe' if is_native_windows() else 'lldb'
    parser.add_argument(
        '--lldb-executable',
        type=str,
        metavar='<file>',
        default=None,
        display_default=defaults.lldb_executable,
        help='location of LLDB executable')


def add_debugger_tool_arguments(parser, context, defaults):
    debuggers = Debuggers(context)
    potential_debuggers = sorted(debuggers.potential_debuggers().keys())

    add_debugger_tool_base_arguments(parser, defaults)

    parser.add_argument(
        '--debugger',
        type=str,
        choices=potential_debuggers,
        required=True,
        help='debugger to use')
    parser.add_argument(
        '--max-steps',
        metavar='<int>',
        type=int,
        default=1000,
        help='maximum number of program steps allowed')
    parser.add_argument(
        '--pause-between-steps',
        metavar='<seconds>',
        type=float,
        default=0.0,
        help='number of seconds to pause between steps')
    defaults.show_debugger = False
    parser.add_argument(
        '--show-debugger',
        action='store_true',
        default=None,
        help='show the debugger')
    defaults.arch = 'x86_64'
    parser.add_argument(
        '--arch',
        type=str,
        metavar='<architecture>',
        default=None,
        display_default=defaults.arch,
        help='target architecture')
    defaults.source_root_dir = ''
    parser.add_argument(
        '--source-root-dir',
        default=None,
        help='prefix path to ignore when matching debug info and source files.')


def handle_debugger_tool_base_options(context, defaults):  # noqa
    options = context.options

    if options.lldb_executable is None:
        options.lldb_executable = defaults.lldb_executable
    else:
        if getattr(options, 'debugger', 'lldb') != 'lldb':
            _warn_meaningless_option(context, '--lldb-executable')

        options.lldb_executable = os.path.abspath(options.lldb_executable)
        if not os.path.isfile(options.lldb_executable):
            raise ToolArgumentError('<d>could not find</> <r>"{}"</>'.format(
                options.lldb_executable))


def handle_debugger_tool_options(context, defaults):  # noqa
    options = context.options

    handle_debugger_tool_base_options(context, defaults)

    if options.arch is None:
        options.arch = defaults.arch
    else:
        if options.debugger != 'lldb':
            _warn_meaningless_option(context, '--arch')

    if options.show_debugger is None:
        options.show_debugger = defaults.show_debugger
    else:
        if options.debugger == 'lldb':
            _warn_meaningless_option(context, '--show-debugger')


def run_debugger_subprocess(debugger_controller, working_dir_path):
    with NamedTemporaryFile(
            dir=working_dir_path, delete=False, mode='wb') as fp:
        pickle.dump(debugger_controller, fp, protocol=pickle.HIGHEST_PROTOCOL)
        controller_path = fp.name

    dexter_py = os.path.basename(sys.argv[0])
    if not os.path.isfile(dexter_py):
        dexter_py = os.path.join(get_root_directory(), '..', dexter_py)
    assert os.path.isfile(dexter_py)

    with NamedTemporaryFile(dir=working_dir_path) as fp:
        args = [
            sys.executable,
            dexter_py,
            'run-debugger-internal-',
            controller_path,
            '--working-directory={}'.format(working_dir_path),
            '--unittest=off',
            '--indent-timer-level={}'.format(Timer.indent + 2)
        ]
        try:
            with Timer('running external debugger process'):
                subprocess.check_call(args)
        except subprocess.CalledProcessError as e:
            raise DebuggerException(e)

    with open(controller_path, 'rb') as fp:
        debugger_controller = pickle.load(fp)

    return debugger_controller


class Debuggers(object):
    @classmethod
    def potential_debuggers(cls):
        try:
            return cls._potential_debuggers
        except AttributeError:
            cls._potential_debuggers = _get_potential_debuggers()
            return cls._potential_debuggers

    def __init__(self, context):
        self.context = context

    def load(self, key):
        with Timer('load {}'.format(key)):
            return Debuggers.potential_debuggers()[key](self.context)

    def _populate_debugger_cache(self):
        debuggers = []
        for key in sorted(Debuggers.potential_debuggers()):
            debugger = self.load(key)

            class LoadedDebugger(object):
                pass

            LoadedDebugger.option_name = key
            LoadedDebugger.full_name = '[{}]'.format(debugger.name)
            LoadedDebugger.is_available = debugger.is_available

            if LoadedDebugger.is_available:
                try:
                    LoadedDebugger.version = debugger.version.splitlines()
                except AttributeError:
                    LoadedDebugger.version = ['']
            else:
                try:
                    LoadedDebugger.error = debugger.loading_error.splitlines()
                except AttributeError:
                    LoadedDebugger.error = ['']

                try:
                    LoadedDebugger.error_trace = debugger.loading_error_trace
                except AttributeError:
                    LoadedDebugger.error_trace = None

            debuggers.append(LoadedDebugger)
        return debuggers

    def list(self):
        debuggers = self._populate_debugger_cache()

        max_o_len = max(len(d.option_name) for d in debuggers)
        max_n_len = max(len(d.full_name) for d in debuggers)

        msgs = []

        for d in debuggers:
            # Option name, right padded with spaces for alignment
            option_name = (
                '{{name: <{}}}'.format(max_o_len).format(name=d.option_name))

            # Full name, right padded with spaces for alignment
            full_name = ('{{name: <{}}}'.format(max_n_len)
                         .format(name=d.full_name))

            if d.is_available:
                name = '<b>{} {}</>'.format(option_name, full_name)

                # If the debugger is available, show the first line of the
                #  version info.
                available = '<g>YES</>'
                info = '<b>({})</>'.format(d.version[0])
            else:
                name = '<y>{} {}</>'.format(option_name, full_name)

                # If the debugger is not available, show the first line of the
                # error reason.
                available = '<r>NO</> '
                info = '<y>({})</>'.format(d.error[0])

            msg = '{} {} {}'.format(name, available, info)

            if self.context.options.verbose:
                # If verbose mode and there was more version or error output
                # than could be displayed in a single line, display the whole
                # lot slightly indented.
                verbose_info = None
                if d.is_available:
                    if d.version[1:]:
                        verbose_info = d.version + ['\n']
                else:
                    # Some of list elems may contain multiple lines, so make
                    # sure each elem is a line of its own.
                    verbose_info = d.error_trace

                if verbose_info:
                    verbose_info = '\n'.join('        {}'.format(l.rstrip())
                                             for l in verbose_info) + '\n'
                    msg = '{}\n\n{}'.format(msg, verbose_info)

            msgs.append(msg)
        self.context.o.auto('\n{}\n\n'.format('\n'.join(msgs)))
