import sys
import traceback
import py4j
from py4j.java_collections import ListConverter

def isJython():
    return  hasattr(sys, 'subversion') and (sys.subversion[0]== 'Jython')


class ReflectiveModule(object):
    def __init__(self, realModule):
        self.realModule = realModule;
        
    def __getattr__( self, name ):
        def wrappedMethod(*args):
            unwrappedArgs = [ unwrap(e) for e in args ]
            result = getattr(self.realModule, name)(*unwrappedArgs)
            return wrap(result);
            
        return wrappedMethod;

class PythonListWrapper:    
    def __init__(self, list):
        self.list = list;
        self.i = 0;
        self.n = list.size();
    
    def __getitem__(self, key):
        obj = self.list[key];
        return wrap(self.list[key]);
    
    def __setitem__(self, key, val):
        self.list[key] = val;
        
    def __iter__(self):
        return self;
    
    def __len__(self):        
        return self.n;
    
    def __next__(self):        
        if self.i < self.n:            
            i = self.i
            self.i += 1
            return wrap(self.list[i]);
        else:
            raise StopIteration()

    def unwrap(self):
        return self.list;
        
    next = __next__  # Alias for Python 2

def getListClass():
     if isJython() :
         #return org.eclipse.papyrus.moka.parametric.semantics.proxy.ValueListProxy
         return org.eclipse.papyrus.moka.engine.suml.accessor.structures.ListAccess
     else:
        return py4j.java_collections.JavaList


def getMapClass():
     if isJython() :
         #return org.eclipse.papyrus.moka.parametric.semantics.proxy.MapProxy
         return org.eclipse.papyrus.moka.engine.suml.accessor.structures.MapAccess
     else:
        return py4j.java_collections.JavaMap

def isOperation(value):
    if not (isinstance(value, py4j.java_gateway.JavaObject)) :
        return False;
    return value.getClass().getName() == "org.eclipse.papyrus.moka.engine.suml.accessor.structures.OperationAccess";

class PythonOperationWrapper:
    def __init__(self, opAccess) :
        self.opAccess = opAccess;
    
    def __call__(self, *arg ):
        return self.opAccess.call(arg);

class PythonWrapper:
    def __init__(self, obj):
        self.__dict__["obj"] = obj;
        
    def __getattr__(self, name):
        if name in self.__dict__ :
            return self.__dict__[name];
        
        if name.startswith('_') :
            if name[1:] in self.__dict__ :
                return self.__dict__[name[1:]];
                
            return wrap(self.__dict__["obj"][name[1:]])
        
        if name in self.__dict__["obj"] :
            return wrap(self.__dict__["obj"][name]);
        
        raise ValueError( "'" + name + "' not found in " + str(self) );

    def __setattr__(self, name, value):        
        if name in self.__dict__ :
            self.__dict__[name] = value;
            return;
        
        if name.startswith('_') :
            self.__dict__["obj"][name[1:]] = unwrap(value);
            return;
        
        if name in self.__dict__["obj"]:
            self.__dict__["obj"][name] = unwrap(value);
            return;
        
        self.__dict__[name] = value;
        
    def __getitem__(self, key):
        return wrap(self.__dict__["obj"].valueAt(key));    
    
    def __str__(self):
        return self.__dict__["obj"].toString()
    
    def unwrap(self):
        return self.__dict__["obj"] 

def unwrap(obj):   
    if isinstance(obj, PythonWrapper):
        return obj.unwrap();
    
    if isinstance(obj, PythonListWrapper):
        return obj.unwrap();
        
    if isinstance(obj, list ) :
        return ListConverter().convert( [ unwrap(e) for e in obj ], gateway._gateway_client)

    return obj;



def wrap(value):    
    if ( value == None ) :
        return value;

    #Already wrapped
    if isinstance(value, PythonWrapper):
        return value;
    

    if isinstance(value, getListClass()):
        return PythonListWrapper(value);
            
    if isinstance(value, getMapClass()):
        return PythonWrapper(value);
        
    if isOperation(value):
        return PythonOperationWrapper(value);
        
    return value;

#print("Python Bootstrap executed.")
