""" pydevd_vars deals with variables:
    resolution/conversion to XML.
"""
import pickle
from django_frame import DjangoTemplateFrame
from pydevd_constants import * #@UnusedWildImport
from types import * #@UnusedWildImport

from pydevd_custom_frames import getCustomFrame
from pydevd_xml import *
from _pydev_imps import _pydev_thread

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO
import sys #@Reimport

import _pydev_threading as threading
import traceback
import pydevd_save_locals
from pydev_imports import Exec, quote, execfile

try:
    import types
    frame_type = types.FrameType
except:
    frame_type = type(sys._getframe())


#-------------------------------------------------------------------------- defining true and false for earlier versions

try:
    __setFalse = False
except:
    import __builtin__
    setattr(__builtin__, 'True', 1)
    setattr(__builtin__, 'False', 0)

#------------------------------------------------------------------------------------------------------ class for errors

class VariableError(RuntimeError):pass

class FrameNotFoundError(RuntimeError):pass

def iterFrames(initialFrame):
    '''NO-YIELD VERSION: Iterates through all the frames starting at the specified frame (which will be the first returned item)'''
    #cannot use yield
    frames = []

    while initialFrame is not None:
        frames.append(initialFrame)
        initialFrame = initialFrame.f_back

    return frames

def dumpFrames(thread_id):
    sys.stdout.write('dumping frames\n')
    if thread_id != GetThreadId(threading.currentThread()):
        raise VariableError("findFrame: must execute on same thread")

    curFrame = GetFrame()
    for frame in iterFrames(curFrame):
        sys.stdout.write('%s\n' % pickle.dumps(frame))


#===============================================================================
# AdditionalFramesContainer
#===============================================================================
class AdditionalFramesContainer:
    lock = _pydev_thread.allocate_lock()
    additional_frames = {} #dict of dicts


def addAdditionalFrameById(thread_id, frames_by_id):
    AdditionalFramesContainer.additional_frames[thread_id] = frames_by_id


def removeAdditionalFrameById(thread_id):
    del AdditionalFramesContainer.additional_frames[thread_id]




def findFrame(thread_id, frame_id):
    """ returns a frame on the thread that has a given frame_id """
    try:
        curr_thread_id = GetThreadId(threading.currentThread())
        if thread_id != curr_thread_id :
            try:
                return getCustomFrame(thread_id, frame_id)  #I.e.: thread_id could be a stackless frame id + thread_id.
            except:
                pass

            raise VariableError("findFrame: must execute on same thread (%s != %s)" % (thread_id, curr_thread_id))

        lookingFor = int(frame_id)

        if AdditionalFramesContainer.additional_frames:
            if DictContains(AdditionalFramesContainer.additional_frames, thread_id):
                frame = AdditionalFramesContainer.additional_frames[thread_id].get(lookingFor)

                if frame is not None:
                    return frame

        curFrame = GetFrame()
        if frame_id == "*":
            return curFrame  # any frame is specified with "*"

        frameFound = None

        for frame in iterFrames(curFrame):
            if lookingFor == id(frame):
                frameFound = frame
                del frame
                break

            del frame

        #Important: python can hold a reference to the frame from the current context
        #if an exception is raised, so, if we don't explicitly add those deletes
        #we might have those variables living much more than we'd want to.

        #I.e.: sys.exc_info holding reference to frame that raises exception (so, other places
        #need to call sys.exc_clear())
        del curFrame

        if frameFound is None:
            msgFrames = ''
            i = 0

            for frame in iterFrames(GetFrame()):
                i += 1
                msgFrames += str(id(frame))
                if i % 5 == 0:
                    msgFrames += '\n'
                else:
                    msgFrames += '  -  '

            errMsg = '''findFrame: frame not found.
    Looking for thread_id:%s, frame_id:%s
    Current     thread_id:%s, available frames:
    %s\n
    ''' % (thread_id, lookingFor, curr_thread_id, msgFrames)

            sys.stderr.write(errMsg)
            return None

        return frameFound
    except:
        import traceback
        traceback.print_exc()
        return None

def getVariable(thread_id, frame_id, scope, attrs):
    """
    returns the value of a variable

    :scope: can be BY_ID, EXPRESSION, GLOBAL, LOCAL, FRAME

    BY_ID means we'll traverse the list of all objects alive to get the object.

    :attrs: after reaching the proper scope, we have to get the attributes until we find
            the proper location (i.e.: obj\tattr1\tattr2)

    :note: when BY_ID is used, the frame_id is considered the id of the object to find and
           not the frame (as we don't care about the frame in this case).
    """
    if scope == 'BY_ID':
        if thread_id != GetThreadId(threading.currentThread()) :
            raise VariableError("getVariable: must execute on same thread")

        try:
            import gc
            objects = gc.get_objects()
        except:
            pass  #Not all python variants have it.
        else:
            frame_id = int(frame_id)
            for var in objects:
                if id(var) == frame_id:
                    if attrs is not None:
                        attrList = attrs.split('\t')
                        for k in attrList:
                            _type, _typeName, resolver = getType(var)
                            var = resolver.resolve(var, k)

                    return var

        #If it didn't return previously, we coudn't find it by id (i.e.: alrceady garbage collected).
        sys.stderr.write('Unable to find object with id: %s\n' % (frame_id,))
        return None

    frame = findFrame(thread_id, frame_id)
    if frame is None:
        return {}

    if attrs is not None:
        attrList = attrs.split('\t')
    else:
        attrList = []

    if scope == 'EXPRESSION':
        for count in xrange(len(attrList)):
            if count == 0:
                # An Expression can be in any scope (globals/locals), therefore it needs to evaluated as an expression
                var = evaluateExpression(thread_id, frame_id, attrList[count], False)
            else:
                _type, _typeName, resolver = getType(var)
                var = resolver.resolve(var, attrList[count])
    else:
        if scope == "GLOBAL":
            var = frame.f_globals
            del attrList[0]  # globals are special, and they get a single dummy unused attribute
        else:
            var = frame.f_locals

        for k in attrList:
            _type, _typeName, resolver = getType(var)
            var = resolver.resolve(var, k)

    return var


def resolveCompoundVariable(thread_id, frame_id, scope, attrs):
    """ returns the value of the compound variable as a dictionary"""

    var = getVariable(thread_id, frame_id, scope, attrs)

    try:
        _type, _typeName, resolver = getType(var)
        return resolver.getDictionary(var)
    except:
        sys.stderr.write('Error evaluating: thread_id: %s\nframe_id: %s\nscope: %s\nattrs: %s\n' % (
            thread_id, frame_id, scope, attrs,))
        traceback.print_exc()


def resolveVar(var, attrs):
    attrList = attrs.split('\t')

    for k in attrList:
        type, _typeName, resolver = getType(var)

        var = resolver.resolve(var, k)

    try:
        type, _typeName, resolver = getType(var)
        return resolver.getDictionary(var)
    except:
        traceback.print_exc()


def customOperation(thread_id, frame_id, scope, attrs, style, code_or_file, operation_fn_name):
    """
    We'll execute the code_or_file and then search in the namespace the operation_fn_name to execute with the given var.

    code_or_file: either some code (i.e.: from pprint import pprint) or a file to be executed.
    operation_fn_name: the name of the operation to execute after the exec (i.e.: pprint)
    """
    expressionValue = getVariable(thread_id, frame_id, scope, attrs)

    try:
        namespace = {'__name__': '<customOperation>'}
        if style == "EXECFILE":
            namespace['__file__'] = code_or_file
            execfile(code_or_file, namespace, namespace)
        else:  # style == EXEC
            namespace['__file__'] = '<customOperationCode>'
            Exec(code_or_file, namespace, namespace)

        return str(namespace[operation_fn_name](expressionValue))
    except:
        traceback.print_exc()


def evaluateExpression(thread_id, frame_id, expression, doExec):
    '''returns the result of the evaluated expression
    @param doExec: determines if we should do an exec or an eval
    '''
    frame = findFrame(thread_id, frame_id)
    if frame is None:
        return

    expression = str(expression.replace('@LINE@', '\n'))


    #Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329
    #(Names not resolved in generator expression in method)
    #See message: http://mail.python.org/pipermail/python-list/2009-January/526522.html
    updated_globals = {}
    updated_globals.update(frame.f_globals)
    updated_globals.update(frame.f_locals)  #locals later because it has precedence over the actual globals

    try:

        if doExec:
            try:
                #try to make it an eval (if it is an eval we can print it, otherwise we'll exec it and
                #it will have whatever the user actually did)
                compiled = compile(expression, '<string>', 'eval')
            except:
                Exec(expression, updated_globals, frame.f_locals)
                pydevd_save_locals.save_locals(frame)
            else:
                result = eval(compiled, updated_globals, frame.f_locals)
                if result is not None:  #Only print if it's not None (as python does)
                    sys.stdout.write('%s\n' % (result,))
            return

        else:
            result = None
            try:
                result = eval(expression, updated_globals, frame.f_locals)
            except Exception:
                s = StringIO()
                traceback.print_exc(file=s)
                result = s.getvalue()

                try:
                    try:
                        etype, value, tb = sys.exc_info()
                        result = value
                    finally:
                        etype = value = tb = None
                except:
                    pass

                result = ExceptionOnEvaluate(result)

                # Ok, we have the initial error message, but let's see if we're dealing with a name mangling error...
                try:
                    if '__' in expression:
                        # Try to handle '__' name mangling...
                        split = expression.split('.')
                        curr = frame.f_locals.get(split[0])
                        for entry in split[1:]:
                            if entry.startswith('__') and not hasattr(curr, entry):
                                entry = '_%s%s' % (curr.__class__.__name__, entry)
                            curr = getattr(curr, entry)

                        result = curr
                except:
                    pass


            return result
    finally:
        #Should not be kept alive if an exception happens and this frame is kept in the stack.
        del updated_globals
        del frame

def changeAttrExpression(thread_id, frame_id, attr, expression):
    '''Changes some attribute in a given frame.
    '''
    frame = findFrame(thread_id, frame_id)
    if frame is None:
        return

    try:
        expression = expression.replace('@LINE@', '\n')

        if isinstance(frame, DjangoTemplateFrame):
            result = eval(expression, frame.f_globals, frame.f_locals)
            frame.changeVariable(attr, result)
            return

        if attr[:7] == "Globals":
            attr = attr[8:]
            if attr in frame.f_globals:
                frame.f_globals[attr] = eval(expression, frame.f_globals, frame.f_locals)
                return frame.f_globals[attr]
        else:
            if pydevd_save_locals.is_save_locals_available():
                frame.f_locals[attr] = eval(expression, frame.f_globals, frame.f_locals)
                pydevd_save_locals.save_locals(frame)
                return

            #default way (only works for changing it in the topmost frame)
            result = eval(expression, frame.f_globals, frame.f_locals)
            Exec('%s=%s' % (attr, expression), frame.f_globals, frame.f_locals)
            return result


    except Exception:
        traceback.print_exc()





