#################################################################################
# Copyright (c) 2019 CEA LIST and others.
# 
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
# which accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
#  Contributors:
#  CEA LIST - Initial API and implementation
#   
#################################################################################
import sys
import os

sys.path.insert(0, os.environ["EASE_PY4J_SRC"])
sys.path.insert(0, os.environ["EASE_PYTHON_COMMON_SRC"])
sys.path.insert(0, os.environ["PY4J_PATH"])


import ease_py4j_main 
from IPython.display import Javascript, display_javascript 

#in IPyhton __builtins__ is a dict, in CPython there is a __builtins__.__dict__ attribute
class IPythonScriptEngineExecute(ease_py4j_main._pyease_ScriptEngineExecute):
      def internalSetVariable(self, name, content):
        self.locals[name] = content
        __builtins__[name] = content  


def connect_to_ease():
  
    javaport = int(os.environ["EASE_JAVA_PORT"])

    import py4j
    from py4j.clientserver import ClientServer, JavaParameters, PythonParameters

   
    engine = IPythonScriptEngineExecute()
    # Bug 517528: Disable memory management until Py4J #275 is resolved
    enable_memory_management = False
    java_params = JavaParameters(auto_convert=True, port=javaport,
                                 enable_memory_management=enable_memory_management)
    
    gateway = ClientServer(java_parameters=java_params,
                          python_parameters=PythonParameters(port=0),
                          python_server_entry_point=engine)
    # retrieve the port on which the python callback server was bound to.
    python_port = gateway.get_callback_server().get_listening_port()
    engine.set_gateway(gateway)
    # tell Java that we are up and running and where to direct
    # calls to python to.
    gateway.entry_point.pythonStartupComplete(python_port, engine)
   

def get_cells_to_run():
    return gateway.entry_point.getCellsToRun()
    
    
    