
''' Generated by OTF2 Template Engine '''

import ctypes
import traceback
import sys

from .Config import conf, StrParam, str_decode
from .ErrorCodes import ErrorCode, HandleErrorCode
from .GeneralDefinitions import *
from .AttributeValue import AttributeValue
from .Definitions import *
from .Callbacks import callback_wrapper
from .IdMap import IdMap


class DefReaderCallbacks(ctypes.Structure):
    pass

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

def DefReaderCallbacks_Delete(defReaderCallbacks):
    c_Delete = conf.lib.OTF2_DefReaderCallbacks_Delete
    c_Delete.argtypes = [ ctypes.POINTER(DefReaderCallbacks) ]
    c_Delete.restype = None
    return c_Delete(defReaderCallbacks)

def DefReaderCallbacks_Clear(defReaderCallbacks):
    c_Clear = conf.lib.OTF2_DefReaderCallbacks_Clear
    c_Clear.argtypes = [ ctypes.POINTER(DefReaderCallbacks) ]
    c_Clear.restype = None
    return c_Clear(defReaderCallbacks)

def _callback_wrapper(type, func, convert_args=None):
    def wrapper(userData, *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)
            ret = func(py_userData, *args)
            if ret is None:
                ret = CALLBACK_SUCCESS
        except:
            sys.stderr.write("An unhandled python exception has occurred in an "
                             "OTF2_DefReaderCallback:\n")
            sys.stderr.write(traceback.format_exc())
            ret = CALLBACK_ERROR
        return ret.value
    return callback_wrapper(func, wrapper, type)

def _convert_property_union(refered_def, name, type, value):
    union = AttributeValue()
    union._arg_value = value
    return refered_def, name, type, union

_DefReaderCallback_FP_Unknown = ctypes.CFUNCTYPE(CallbackCode, ctypes.c_void_p)

@otf2 for def in defs|local_defs:
_DefReaderCallback_FP_@@def.name@@ = ctypes.CFUNCTYPE(CallbackCode, ctypes.c_void_p@@def.py_funcargtypes(argtypes=false)@@)

@otf2 endfor
def DefReaderCallbacks_SetUnknownCallback(defReaderCallbacks, unknownCallback):
    c_SetUnknownCallback = conf.lib.OTF2_DefReaderCallbacks_SetUnknownCallback
    c_SetUnknownCallback.argtypes = [ ctypes.POINTER(DefReaderCallbacks), _DefReaderCallback_FP_Unknown ]
    c_SetUnknownCallback.restype = ErrorCode
    c_SetUnknownCallback.errcheck = HandleErrorCode
    wrapped_callback = _callback_wrapper(_DefReaderCallback_FP_Unknown,
                                         unknownCallback)
    c_SetUnknownCallback(defReaderCallbacks, wrapped_callback)

@otf2 for def in defs|local_defs:
@otf2  if def == String:
def DefReaderCallbacks_SetStringCallback(defReaderCallbacks, stringCallback):
    c_SetStringCallback = conf.lib.OTF2_DefReaderCallbacks_SetStringCallback
    c_SetStringCallback.argtypes = [ ctypes.POINTER(DefReaderCallbacks), _DefReaderCallback_FP_String ]
    c_SetStringCallback.restype = ErrorCode
    c_SetStringCallback.errcheck = HandleErrorCode
    def convert_string(ref, name):
        return ref, str_decode(name)
    wrapped_callback = _callback_wrapper(_DefReaderCallback_FP_String,
                                         stringCallback, convert_string)
    c_SetStringCallback(defReaderCallbacks, wrapped_callback)

@otf2  elif def == Group:
def DefReaderCallbacks_SetGroupCallback(defReaderCallbacks, groupCallback):
    c_SetGroupCallback = conf.lib.OTF2_DefReaderCallbacks_SetGroupCallback
    c_SetGroupCallback.argtypes = [ ctypes.POINTER(DefReaderCallbacks), _DefReaderCallback_FP_Group ]
    c_SetGroupCallback.restype = ErrorCode
    c_SetGroupCallback.errcheck = HandleErrorCode
    def convert_group(ref, name, group_type, paradigm, group_flags, number_of_metrics,
                      members_array):
        members = [members_array[i] for i in range(number_of_metrics)]
        return ref, name, group_type, paradigm, group_flags, members
    wrapped_callback = _callback_wrapper(_DefReaderCallback_FP_Group,
                                         groupCallback, convert_group)
    c_SetGroupCallback(defReaderCallbacks, wrapped_callback)

@otf2  elif def == MetricClass:
def DefReaderCallbacks_SetMetricClassCallback(defReaderCallbacks, metricClassCallback):
    c_SetMetricClassCallback = conf.lib.OTF2_DefReaderCallbacks_SetMetricClassCallback
    c_SetMetricClassCallback.argtypes = [ ctypes.POINTER(DefReaderCallbacks), _DefReaderCallback_FP_MetricClass ]
    c_SetMetricClassCallback.restype = ErrorCode
    c_SetMetricClassCallback.errcheck = HandleErrorCode
    def convert_metric_class(ref, number_of_metrics, metric_members_array, metric_occurrence,
                             recorder_kind):
        metric_members = [metric_members_array[i] for i in range(number_of_metrics)]
        return ref, metric_members, metric_occurrence, recorder_kind
    wrapped_callback = _callback_wrapper(_DefReaderCallback_FP_MetricClass,
                                         metricClassCallback, convert_metric_class)
    c_SetMetricClassCallback(defReaderCallbacks, wrapped_callback)

@otf2  elif def == CartTopology:
def DefReaderCallbacks_SetCartTopologyCallback(defReaderCallbacks, cartTopologyCallback):
    c_SetCartTopologyCallback = conf.lib.OTF2_DefReaderCallbacks_SetCartTopologyCallback
    c_SetCartTopologyCallback.argtypes = [ ctypes.POINTER(DefReaderCallbacks), _DefReaderCallback_FP_CartTopology ]
    c_SetCartTopologyCallback.restype = ErrorCode
    c_SetCartTopologyCallback.errcheck = HandleErrorCode
    def convert_cart_topology(ref, name, communicator, number_of_dimensions,
                              cart_dimensions_array):
        cart_dimensions = [cart_dimensions_array[i] for i in range(number_of_dimensions)]
        return ref, name, communicator, cart_dimensions
    wrapped_callback = _callback_wrapper(_DefReaderCallback_FP_CartTopology,
                                         cartTopologyCallback, convert_cart_topology)
    c_SetCartTopologyCallback(defReaderCallbacks, wrapped_callback)

@otf2  elif def == CartCoordinate:
def DefReaderCallbacks_SetCartCoordinateCallback(defReaderCallbacks, cartCoordinateCallback):
    c_SetCartCoordinateCallback = conf.lib.OTF2_DefReaderCallbacks_SetCartCoordinateCallback
    c_SetCartCoordinateCallback.argtypes = [ ctypes.POINTER(DefReaderCallbacks), _DefReaderCallback_FP_CartCoordinate ]
    c_SetCartCoordinateCallback.restype = ErrorCode
    c_SetCartCoordinateCallback.errcheck = HandleErrorCode
    def convert_cart_coordinate(cart_topology, rank, number_of_dimensions, coordinates_array):
        coordinates = [coordinates_array[i] for i in range(number_of_dimensions)]
        return cart_topology, rank, coordinates
    wrapped_callback = _callback_wrapper(_DefReaderCallback_FP_CartCoordinate,
                                         cartCoordinateCallback, convert_cart_coordinate)
    c_SetCartCoordinateCallback(defReaderCallbacks, wrapped_callback)

@otf2  else:
def DefReaderCallbacks_Set@@def.name@@Callback(defReaderCallbacks, @@def.lname@@Callback):
    c_Set@@def.name@@Callback = conf.lib.OTF2_DefReaderCallbacks_Set@@def.name@@Callback
    c_Set@@def.name@@Callback.argtypes = [ ctypes.POINTER(DefReaderCallbacks), _DefReaderCallback_FP_@@def.name@@ ]
    c_Set@@def.name@@Callback.restype = ErrorCode
    c_Set@@def.name@@Callback.errcheck = HandleErrorCode
    @otf2 if def.name[-8:] == 'Property' or def.name == 'CallpathParameter':
    convert = _convert_property_union
    @otf2 else:
    convert = None
    @otf2 endif
    wrapped_callback = _callback_wrapper(_DefReaderCallback_FP_@@def.name@@,
                                         @@def.lname@@Callback,
                                         convert)
    c_Set@@def.name@@Callback(defReaderCallbacks, wrapped_callback)

@otf2  endif
@otf2 endfor
__all__ = [
    'DefReaderCallbacks',
    'DefReaderCallbacks_New',
    'DefReaderCallbacks_Delete',
    'DefReaderCallbacks_Clear',
    'DefReaderCallbacks_SetUnknownCallback',
    @otf2 for def in defs|local_defs:
    'DefReaderCallbacks_Set@@def.name@@Callback',
    @otf2 endfor
]
