'''
Copyright (c) 2018 Martin Kloesch
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v2.0
which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-2.0/

Contributors:
 * Martin Kloesch - initial API and implementation
'''

# Python std library imports
import ast as _pyease_ast
import bdb as _pyease_bdb
import functools as _pyease_functools
import re as _pyease_re
import sys as _pyease_sys
import threading as _pyease_threading

# : Regular expression if we are dealing with internal module.
_pyease_INTERNAL_CHECKER = _pyease_re.compile(r'^<.+>$')


class _pyease_PyFrame:
    '''
    Python implementation of IPyFrame used for exchanging frame data
    with eclipse.

    Simply wraps standard python frame to more easily usable format.

    Python frame documentation is available here:
    https://docs.python.org/3/reference/datamodel.html#types
    '''

    def __init__(self, frame):
        '''
        Constructor only stores frame to member.

        :param frame:    Python frame to be converted.
        '''
        self._frame = frame

    def _valid_frame(self):
        '''
        Utility method checking if the current frame is valid

        A frame is valid if all information is present and
        it's file is not ignored.

        :returns:    ``True`` if frame is valid.
        '''
        return self._frame and not _pyease_ignore_frame(self._frame)

    def getFilename(self):
        '''
        Returns the filename of the frame.

        If no frame was set, a dummy value will be returned.

        :returns:    Filename of frame or dummy value.
        '''
        if self._valid_frame():
            return self._frame.f_code.co_filename
        else:
            return '__no_frame__'

    def getLineNumber(self):
        '''
        Returns the linenumber of the frame.

        If no frame was set, -1 is returned.

        :returns:    Line number of frame or -1.
        '''
        if self._valid_frame():
            return self._frame.f_lineno
        else:
            return -1

    def getParent(self):
        '''
        Returns the parent of the frame.

        If no frame was set or the frame does not have a parent
        `None` is returned.

        :returns:    Parent frame in stack or `None`
        '''
        if self._valid_frame():
            return _pyease_PyFrame(self._frame.f_back)
        else:
            return None

    def getVariable(self, name):
        '''
        Get a variable from the current frame.

        :param: name:   variable name to look up
        :return:        variable or <code>null</code>
        '''
        if self._valid_frame():
            if name in self._frame.f_locals:
                return convert_value(self._frame.f_locals[name])

            if name in self._frame.f_globals:
                return convert_value(self._frame.f_globals[name])

        return None

    def getVariables(self):
        '''
        Get variables visible from current frame.

        :return:        variableName -> variableContent
        '''
        variables = {}
        if self._valid_frame():
            # TODO: Differentiate between global and local variables
            variables.update(self._frame.f_globals)
            variables.update(self._frame.f_locals)

        return convert_value(variables)

    def setVariable(self, name, value):
        '''
        Sets new value for a variable only if it exists.

        :param name:    Name of variable to be updated.
        :param value:   New value for variable.
        '''
        if self._valid_frame():
            if name in self._frame.f_locals:
                self._frame.f_locals[name] = value

            elif name in self._frame.f_globals:
                self._frame.f_globals[name] = value

    def toString(self):
        '''
        Required override to avoid problems in py4j bridge.
        '''
        return '{}: #{:d}'.format(self.getFilename(), self.getLineNumber())

    class Java:
        implements = ['org.eclipse.ease.lang.python.debugger.IPyFrame']


def _pyease_ignore_frame(frame, first=True):
    '''
    Utility to check if a frame should be ignored.

    Current reasons to ignore a frame:
        * It is the top entry of the stack and it is a standard module.
          e.g. <string>
        * It is part of the py4j library or has py4j in its call chain.

    Recursively checks trace until at bottom of stack.

    :param frame:    Frame to check if it should be ignored.
    :param first:    Flag to signalize if it is the first call.
    :returns:        `True` if the frame should be ignored.
    '''
    # End of frame
    if not frame:
        return False

    # ignore frames that originate from the self.run() method
    if first:
        if frame.f_code.co_filename == '(none)':
            return True

    # Check if we are in the standard modules
    if _pyease_INTERNAL_CHECKER.match(frame.f_code.co_filename):
        # Only ignore standard module if its the top of the stack
        return first

    # TODO: Think of better way to identify py4j library
    if 'py4j' in frame.f_code.co_filename.lower():
        return True

    return _pyease_ignore_frame(frame.f_back, False)


class _pyease_CodeTracer(_pyease_bdb.Bdb):
    '''
    Eclipse Debugger class.
    '''

    def __init__(self, *args, **kwargs):
        '''
        Constructor initializes instance variables.
        '''
        _pyease_bdb.Bdb.__init__(self, *args, **kwargs)

        # Debugger for communication with Java world
        self._debugger = None

        # Caches for currently executed code parts
        self._current_frame = None
        self._current_file = None

        # Async continuation handling
        self._continue_event = _pyease_threading.Event()
        self._continue_func = lambda: None

        # TODO: Think about a better way to handle step return
        self._return_hack = False

    def setDebugger(self, debugger):
        '''
        Setter method for self._debugger.

        :param org.eclipse.ease.lang.python.debugger.PythonDebugger debugger:
            PythonDebugger object to handling communication with Eclipse.
        '''
        self._debugger = debugger

    def trace_dispatch(self, frame, event, arg):
        '''
        Called for every executed line of source code.

        Checks if line is of interest and dispatches the call for
        further investigation.

        :param frame:    Current stack frame.
        :param event:    Type of dispatch event that occurred.
        :param arg:      Optional argument for dispatching.
        '''
        # Pre-filter to avoid issues with library internals
        if not _pyease_ignore_frame(frame):
            _pyease_bdb.Bdb.trace_dispatch(self, frame, event, arg)
        return self.trace_dispatch

    def user_line(self, frame):
        '''
        Called when debugger thinks line is of interest.

        :param frame:    Current stack frame with line.
        '''
        self._continue_func = self.set_continue
        self.dispatch(frame, 'line')

    def user_call(self, frame, argument_list):
        '''
        Called when debugger thinks call is of interest.

        :param frame:    Current stack frame with call information.
        :param argument_list:    ignored
        '''
        self.dispatch(frame, 'call')

    def user_return(self, frame, return_value):
        '''
        Called when debugger thinks returning from function is of interest.

        :param frame:    Current stack frame with return information.
        :param return_value:    ignored
        '''
        self._continue_func = self.set_step
        self.dispatch(frame, 'return')

    def user_exception(self, frame, exc_info):
        '''
        Called when debugger thinks thrown exception is of interest.

        :param frame:    Current stack frame with exception information.
        :param exc_info:    ignored
        '''
        # Cache exception
        if self._debugger:
            self._debugger.setExceptionStackTrace(_pyease_PyFrame(frame))

        self._continue_func = self.set_continue
        self.dispatch(frame, 'exception')

    def dispatch(self, frame, dispatch_type):
        '''
        Dispatches the given frame to the interested debugger.

        :param frame:    Current stack frame to be dispatched.
        :param dispatch_type:    Type of dispatch event (call, line, ...)
        '''
        if not self._debugger:
            return

        # Set up caches for asynchronous continuation
        self._current_frame = frame
        self._continue_event.set()

        # Check if we need to fake the current frame for Eclipse
        if self._return_hack:
            frame = frame.f_back
            self._return_hack = False

        # Dispatch call to Java
        self._debugger.traceDispatch(_pyease_PyFrame(frame), dispatch_type)

        # Make asynchronous call synchronous again
        self._continue_event.wait()
        self._continue_func()

    def suspend(self):
        '''
        Suspend the execution to wait for asynchronous callbacks
        from Java.
        '''
        self._continue_event.clear()

    def resume(self, resume_type):
        '''
        Resume execution by calling the given resume function.

        :param resume_type:    Desired resume function identifier.
        '''
        frame = self._current_frame

        # Step into
        if resume_type == 1:
            self._continue_func = self.set_step

        # Step over
        elif resume_type == 2:
            self._continue_func = _pyease_functools.partial(self.set_next, frame)

        # Step return
        elif resume_type == 4:
            self._return_hack = True
            self._continue_func = _pyease_functools.partial(self.set_return, frame)

        # Continue
        else:
            self._continue_func = self.set_continue

        self._continue_event.set()

    def set_continue(self):
        '''
        FIXME:  Override of bdb.Bdb.set_continue
                Original stops debugging when no more breakpoints in file.
                This means we cannot add breakpoints later on.
        '''
        self._set_stopinfo(self.botframe, None, -1)

    def setBreakpoint(self, breakpoint):
        '''
        Interface method for Java to have simpler method of setting
        a breakpoint.

        FIXME:  This is a copy of bdb.Bdb.set_break
                set_break performs OS level checks to see if file exists.

        :param breakpoint:    Breakpoint to be set.
        '''
        filename = self.canonic(breakpoint.getFilename())
        lineno = breakpoint.getLineno()

        if filename not in self.breaks:
            self.breaks[filename] = []
        linenos = self.breaks[filename]
        if lineno not in linenos:
            linenos .append(lineno)
        _pyease_bdb.Breakpoint(filename, lineno, 0, None, None)

    def removeBreakpoint(self, breakpoint):
        '''
        Interface method for Java to have simpler method of removing
        a breakpoint.

        :param breakpoint:    Breakpoint to be removed.
        '''
        filename = self.canonic(breakpoint.getFilename())
        lineno = breakpoint.getLineno()
        self.clear_break(filename, lineno)

    def stop_here(self, frame):
        '''
        Hijacks frame check to see if currently executed file has changed.

        If file changed new breakpoints will be loaded.

        :param frame:    Current stack frame to check for file change.
        '''
        if self._debugger:
            file = frame.f_code.co_filename
            if file != self._current_file:
                self._current_file = file
                self.clear_all_file_breaks(file)

                breakpoints = self._debugger.getBreakpoints(file)
                for breakpoint in breakpoints:
                    self.setBreakpoint(breakpoint)

                # If we have breakpoints we want to let the debugger know
                if breakpoints:
                    return True

        return _pyease_bdb.Bdb.stop_here(self, frame)

    def run(self, script, filename):
        '''
        Executes the script given using the bdb.Bdb.run method.

        :param script:    Script to be executed.
        :param filename:  Filename for easier identification of dynamic code.
        '''
        # Compile code for better inspection
        code = '{}\n'.format(script.getCode())
        ast_ = _pyease_ast.parse(code, filename, 'exec')
        final_expr = None
        for field_ in _pyease_ast.iter_fields(ast_):
            if 'body' != field_[0]:
                continue

            # Check if last item is an expression
            if len(field_[1]) > 0:
                if isinstance(field_[1][-1], _pyease_ast.Expr):
                    final_expr = _pyease_ast.Expression()
                    popped = field_[1].pop(-1)
                    final_expr.body = popped.value

        # Run code up to last expression
        return_value = None
        compiled = compile(ast_, filename, 'exec')
        _pyease_bdb.Bdb.run(self, compiled)
        self._keep_debugging()

        # Check if last expression still needs to be run
        if final_expr:
            compiled = compile(final_expr, filename, 'eval')
            return_value = self.runeval(compiled)
            self._keep_debugging()

        return return_value

    def _keep_debugging(self):
        '''
        Resets debugger state to be able to continue debugging after
        script injection.
        '''
        _pyease_sys.settrace(self.trace_dispatch)
        self.quitting = False

    def toString(self):
        '''
        Required override to avoid problems in py4j bridge.
        '''
        return str(self)

    def equals(self, other):
        '''
        Required override to avoid problems in py4j bridge.
        '''
        return self is other

    class Java:
        implements = ['org.eclipse.ease.lang.python.py4j.internal.ICodeTraceFilter']


# Set up connection between eclipse and python
_pyease_CodeTracer()