import inspect
import os

try:
    import trace
except ImportError:
    pass
else:
    trace._warn = lambda *args: None   # workaround for http://bugs.python.org/issue17143 (PY-8706)

import gc
from pydevd_comm import CMD_SIGNATURE_CALL_TRACE, NetCommand
import pydevd_vars
from pydevd_constants import xrange

class Signature(object):
    def __init__(self, file, name):
        self.file = file
        self.name = name
        self.args = []
        self.args_str = []

    def add_arg(self, name, type):
        self.args.append((name, type))
        self.args_str.append("%s:%s"%(name, type))

    def __str__(self):
        return "%s %s(%s)"%(self.file, self.name, ", ".join(self.args_str))


class SignatureFactory(object):
    def __init__(self):
        self._caller_cache = {}
        self.project_roots =  os.getenv('PYCHARM_PROJECT_ROOTS', '').split(os.pathsep)

    def is_in_scope(self, filename):
        filename = os.path.normcase(filename)
        for root in self.project_roots:
            root = os.path.normcase(root)
            if filename.startswith(root):
                return True
        return False



    def create_signature(self, frame):
        try:
            code = frame.f_code
            locals = frame.f_locals
            filename, modulename, funcname = self.file_module_function_of(frame)
            res = Signature(filename, funcname)
            for i in xrange(0, code.co_argcount):
                name = code.co_varnames[i]
                tp = type(locals[name])
                class_name = tp.__name__
                if class_name == 'instance':  # old-style classes
                    tp = locals[name].__class__
                    class_name = tp.__name__

                if tp.__module__ and tp.__module__ != '__main__':
                    class_name = "%s.%s"%(tp.__module__, class_name)

                res.add_arg(name, class_name)
            return res
        except:
            import traceback
            traceback.print_exc()


    def file_module_function_of(self, frame): #this code is take from trace module and fixed to work with new-style classes
        code = frame.f_code
        filename = code.co_filename
        if filename:
            modulename = trace.modname(filename)
        else:
            modulename = None

        funcname = code.co_name
        clsname = None
        if code in self._caller_cache:
            if self._caller_cache[code] is not None:
                clsname = self._caller_cache[code]
        else:
            self._caller_cache[code] = None
            ## use of gc.get_referrers() was suggested by Michael Hudson
            # all functions which refer to this code object
            funcs = [f for f in gc.get_referrers(code)
                     if inspect.isfunction(f)]
            # require len(func) == 1 to avoid ambiguity caused by calls to
            # new.function(): "In the face of ambiguity, refuse the
            # temptation to guess."
            if len(funcs) == 1:
                dicts = [d for d in gc.get_referrers(funcs[0])
                         if isinstance(d, dict)]
                if len(dicts) == 1:
                    classes = [c for c in gc.get_referrers(dicts[0])
                               if hasattr(c, "__bases__") or inspect.isclass(c)]
                elif len(dicts) > 1:   #new-style classes
                    classes = [c for c in gc.get_referrers(dicts[1])
                               if hasattr(c, "__bases__") or inspect.isclass(c)]
                else:
                    classes = []

                if len(classes) == 1:
                    # ditto for new.classobj()
                    clsname = classes[0].__name__
                    # cache the result - assumption is that new.* is
                    # not called later to disturb this relationship
                    # _caller_cache could be flushed if functions in
                    # the new module get called.
                    self._caller_cache[code] = clsname


        if clsname is not None:
            funcname = "%s.%s" % (clsname, funcname)

        return filename, modulename, funcname

def create_signature_message(signature):
    cmdTextList = ["<xml>"]

    cmdTextList.append('<call_signature file="%s" name="%s">' % (pydevd_vars.makeValidXmlValue(signature.file), pydevd_vars.makeValidXmlValue(signature.name)))

    for arg in signature.args:
        cmdTextList.append('<arg name="%s" type="%s"></arg>' % (pydevd_vars.makeValidXmlValue(arg[0]), pydevd_vars.makeValidXmlValue(arg[1])))

    cmdTextList.append("</call_signature></xml>")
    cmdText = ''.join(cmdTextList)
    return NetCommand(CMD_SIGNATURE_CALL_TRACE, 0, cmdText)

def sendSignatureCallTrace(dbg, frame, filename):
    if dbg.signature_factory.is_in_scope(filename):
        dbg.writer.addCommand(create_signature_message(dbg.signature_factory.create_signature(frame)))



