"""

"""

import tempfile
import os

import System
from System.IO import File
from System.IO import FileMode
from System.Runtime.Serialization.Formatters.Binary import BinaryFormatter


def ExecuteCommand(api, cmd, **args):
    """
    Execute the command in the WB journaling engine. 
    The args can be retreive in the journaling scope.
    The returnValue(value) fuction can be call from the journaling.
    """
    sd, in_file = tempfile.mkstemp() ; os.close(sd)
    sd, out_file = tempfile.mkstemp() ; os.close(sd)

    _serialize(in_file, args)

    code = _getCode(in_file, out_file, args) + cmd
    api.Application.ScriptByName('journaling').ExecuteCommand(code)

    result = _deserialize(out_file)

    try: os.remove(in_file)
    except: pass 
    try: os.remove(out_file)
    except: pass

    return result


def ExecuteFile(api, file, **args):
    """
    Execute the file in the WB journaling engine. 
    The args can be retreive in the journaling scope.
    The returnValue(value) fuction can be call from the journaling.
    """
    with open(file, 'r') as f:
        cmd = f.read()
        return ExecuteCommand(api, cmd, **args)

#-------------------------------
#   Serialize / Deserialize
#-------------------------------

def _serialize(file, value):
    stream = None
    fm = BinaryFormatter()
    try: 
        stream = File.Create(file)
        fm.Serialize(stream, value)
    except: 
        pass
    if stream != None: 
        stream.Close()

def _deserialize(file):
    value = None
    stream = None
    fm = BinaryFormatter()
    try: 
        stream = File.Open(file, FileMode.Open)
        value = fm.Deserialize(stream)
    except: 
        pass
    if stream != None: 
        stream.Close()
    return value

#-------------------------------
#   Remode code
#-------------------------------

def _getCode(in_file, out_file, args):

    code = ''
    
    code += 'import System\n'
    code += 'from System.IO import File\n'
    code += 'from System.IO import FileMode\n'
    code += 'from System.Runtime.Serialization.Formatters.Binary import BinaryFormatter\n'
    code += '\n'

    code += 'def _serialize(file, value):\n'
    code += '    stream = None\n'
    code += '    fm = BinaryFormatter()\n'
    code += '    try:\n'
    code += '        stream = File.Create(file)\n'
    code += '        fm.Serialize(stream, value)\n'
    code += '    except:\n'
    code += '        pass\n'
    code += '    if stream != None: stream.Close()\n'
    code += '\n'

    code += 'def _deserialize(file):\n'
    code += '    value = None\n'
    code += '    stream = None\n'
    code += '    fm = BinaryFormatter()\n'
    code += '    try:\n'
    code += '        stream = File.Open(file, FileMode.Open)\n'
    code += '        value = fm.Deserialize(stream)\n'
    code += '    except:\n'
    code += '        pass\n'
    code += '    if stream != None: stream.Close()\n'
    code += '    return value\n'
    code += '\n'

    code += 'def returnValue(value):\n'
    code += '    _serialize(r"{0}", value)\n'.format(out_file)
    code += '\n'

    code += '_in_args = _deserialize(r"{0}")\n'.format(in_file)
    for key in args.iterkeys():
        code += '{0} = _in_args["{0}"]\n'.format(key)
    code += '\n'
    code += '\n'

    return code

