
''' Generated by OTF2 Template Engine '''

import ctypes
import traceback
import sys

from .Config import conf, StrParam
from .ErrorCodes import ErrorCode, HandleErrorCode
from .GeneralDefinitions import *
from .AttributeList import AttributeList
from .Definitions import *
from .Events import *
from .Callbacks import callback_wrapper


class GlobalEvtReaderCallbacks(ctypes.Structure):
    pass

def GlobalEvtReaderCallbacks_New():
    c_New = conf.lib.OTF2_GlobalEvtReaderCallbacks_New
    c_New.argtypes = []
    c_New.restype = ctypes.POINTER(GlobalEvtReaderCallbacks)
    # NOTE: Do not errcheck here. This function returns a value, not an error code
    return c_New()

def GlobalEvtReaderCallbacks_Delete(globalEvtReaderCallbacks):
    c_Delete = conf.lib.OTF2_GlobalEvtReaderCallbacks_Delete
    c_Delete.argtypes = [ ctypes.POINTER(GlobalEvtReaderCallbacks) ]
    c_Delete.restype = None
    return c_Delete(globalEvtReaderCallbacks)

def GlobalEvtReaderCallbacks_Clear(globalEvtReaderCallbacks):
    c_Clear = conf.lib.OTF2_GlobalEvtReaderCallbacks_Clear
    c_Clear.argtypes = [ ctypes.POINTER(GlobalEvtReaderCallbacks) ]
    c_Clear.restype = None
    return c_Clear(globalEvtReaderCallbacks)

def _callback_wrapper(type, func, convert_args=None):
    def wrapper(location, time, userData, attribute_list, *args):
        if userData:
            py_userData = ctypes.cast(userData, ctypes.py_object).value
        else:
            py_userData = None
        try:
            if convert_args is not None:
                args = convert_args(*args)
            if not attribute_list:
                attribute_list = None
            ret = func(location, time, py_userData, attribute_list, *args)
            if ret is None:
                ret = CALLBACK_SUCCESS
        except:
            sys.stderr.write("An unhandled python exception has occurred in an "
                             "OTF2_GlobalEvtReaderCallback:\n")
            sys.stderr.write(traceback.format_exc())
            ret = CALLBACK_ERROR
        return ret.value
    return callback_wrapper(func, wrapper, type)

_GlobalEvtReaderCallback_FP_Unknown = ctypes.CFUNCTYPE(CallbackCode,
        LocationRef, TimeStamp, ctypes.c_void_p,
        ctypes.POINTER(AttributeList))

@otf2 for event in events:
_GlobalEvtReaderCallback_FP_@@event.name@@ = ctypes.CFUNCTYPE(CallbackCode,
        LocationRef, TimeStamp, ctypes.c_void_p,
        ctypes.POINTER(AttributeList)@@event.py_funcargtypes(argtypes=False)@@)

@otf2 endfor
def GlobalEvtReaderCallbacks_SetUnknownCallback(globalEvtReaderCallbacks, unknownCallback):
    c_SetUnknownCallback = conf.lib.OTF2_GlobalEvtReaderCallbacks_SetUnknownCallback
    c_SetUnknownCallback.argtypes = [ ctypes.POINTER(GlobalEvtReaderCallbacks), _GlobalEvtReaderCallback_FP_Unknown ]
    c_SetUnknownCallback.restype = ErrorCode
    c_SetUnknownCallback.errcheck = HandleErrorCode
    wrapped_callback = _callback_wrapper(_GlobalEvtReaderCallback_FP_Unknown,
                                         unknownCallback)
    c_SetUnknownCallback(globalEvtReaderCallbacks, wrapped_callback)

@otf2 for event in events:
@otf2  if event == Metric:
def GlobalEvtReaderCallbacks_SetMetricCallback(globalEvtReaderCallbacks, metricCallback):
    c_SetMetricCallback = conf.lib.OTF2_GlobalEvtReaderCallbacks_SetMetricCallback
    c_SetMetricCallback.argtypes = [ ctypes.POINTER(GlobalEvtReaderCallbacks), _GlobalEvtReaderCallback_FP_Metric ]
    c_SetMetricCallback.restype = ErrorCode
    c_SetMetricCallback.errcheck = HandleErrorCode
    def convert_args_metric(metric, number_of_metrics, type_ids_array, metric_values_array):
        type_ids = [type_ids_array[i] for i in range(number_of_metrics)]
        metric_values = [metric_values_array[i] for i in range(number_of_metrics)]
        return metric, type_ids, metric_values
    wrapped_callback = _callback_wrapper(_GlobalEvtReaderCallback_FP_Metric,
                                         metricCallback, convert_args_metric)
    c_SetMetricCallback(globalEvtReaderCallbacks, wrapped_callback)

@otf2  elif event == ProgramBegin:
def GlobalEvtReaderCallbacks_SetProgramBeginCallback(globalEvtReaderCallbacks, programBeginCallback):
    c_SetProgramBeginCallback = conf.lib.OTF2_GlobalEvtReaderCallbacks_SetProgramBeginCallback
    c_SetProgramBeginCallback.argtypes = [ ctypes.POINTER(GlobalEvtReaderCallbacks), _GlobalEvtReaderCallback_FP_ProgramBegin ]
    c_SetProgramBeginCallback.restype = ErrorCode
    c_SetProgramBeginCallback.errcheck = HandleErrorCode
    def convert_args(program_name, number_of_arguments, arguments_array):
        arguments = [arguments_array[i] for i in range(number_of_arguments)]
        return program_name, arguments
    wrapped_callback = _callback_wrapper(_GlobalEvtReaderCallback_FP_ProgramBegin,
                                         programBeginCallback, convert_args)
    c_SetProgramBeginCallback(globalEvtReaderCallbacks, wrapped_callback)

@otf2  else:
def GlobalEvtReaderCallbacks_Set@@event.name@@Callback(globalEvtReaderCallbacks, @@event.lname@@Callback):
    c_Set@@event.name@@Callback = conf.lib.OTF2_GlobalEvtReaderCallbacks_Set@@event.name@@Callback
    c_Set@@event.name@@Callback.argtypes = [ ctypes.POINTER(GlobalEvtReaderCallbacks), _GlobalEvtReaderCallback_FP_@@event.name@@ ]
    c_Set@@event.name@@Callback.restype = ErrorCode
    c_Set@@event.name@@Callback.errcheck = HandleErrorCode
    wrapped_callback = _callback_wrapper(_GlobalEvtReaderCallback_FP_@@event.name@@,
                                         @@event.lname@@Callback)
    c_Set@@event.name@@Callback(globalEvtReaderCallbacks, wrapped_callback)

@otf2  endif
@otf2 endfor
__all__ = [
    'GlobalEvtReaderCallbacks',
    'GlobalEvtReaderCallbacks_New',
    'GlobalEvtReaderCallbacks_Delete',
    'GlobalEvtReaderCallbacks_Clear',
    'GlobalEvtReaderCallbacks_SetUnknownCallback',
    @otf2 for event in events:
    'GlobalEvtReaderCallbacks_Set@@event.name@@Callback',
    @otf2 endfor
]
