# AUTOGENERATED FILE - DO NOT MODIFY!
# This file generated by Djinni from foo_listener_bf.djinni

from djinni.support import MultiSet # default imported in all files
from djinni.exception import CPyException # default imported in all files
from djinni.pycffi_marshal import CPyBinary, CPyString

from abc import ABCMeta, abstractmethod
from future.utils import with_metaclass
from PyCFFIlib_cffi import ffi, lib

from djinni import exception # this forces run of __init__.py which gives cpp option to call back into py to create exception

class FooListenerBf(with_metaclass(ABCMeta)):
    @abstractmethod
    def on_string_change(self, private_string):
        raise NotImplementedError

    @abstractmethod
    def get_string(self):
        raise NotImplementedError

    @abstractmethod
    def set_listener_bf(self, listener):
        raise NotImplementedError

    @abstractmethod
    def get_listener_bf(self):
        raise NotImplementedError

    @abstractmethod
    def set_binary(self, b):
        raise NotImplementedError

    @abstractmethod
    def get_binary(self):
        raise NotImplementedError

    @abstractmethod
    def send_return(self, fl_bf):
        raise NotImplementedError

    @abstractmethod
    def delete_fl_in_fl(self):
        raise NotImplementedError

    @staticmethod
    def create():
        return FooListenerBfCppProxy.create()

class FooListenerBfCppProxy(FooListenerBf):
    def __init__(self, proxy):
        self._is_cpp_proxy = True
        self._cpp_impl = proxy
    def __del__(self):
        if not lib:
            return
        lib.foo_listener_bf___wrapper_dec_ref(self._cpp_impl)

    def on_string_change(self, private_string):
        with CPyString.fromPy(private_string) as pys_private_string:
            _ret_c = lib.cw__foo_listener_bf_on_string_change(self._cpp_impl, pys_private_string.release_djinni_string())
            CPyException.toPyCheckAndRaise(_ret_c)
            _ret = CPyString.toPy(_ret_c)
            assert _ret is not None
            return _ret

    def get_string(self):
        _ret_c = lib.cw__foo_listener_bf_get_string(self._cpp_impl)
        CPyException.toPyCheckAndRaise(_ret_c)
        _ret = CPyString.toPy(_ret_c)
        assert _ret is not None
        return _ret

    @staticmethod
    def create():
        _ret_c = lib.cw__foo_listener_bf_create()
        CPyException.toPyCheckAndRaise(_ret_c)
        _ret = FooListenerBfHelper.toPy(_ret_c)
        assert _ret is not None
        return _ret

    def set_listener_bf(self, listener):
        lib.cw__foo_listener_bf_set_listener_bf(self._cpp_impl, FooListenerBfHelper.fromPy(listener))
        CPyException.toPyCheckAndRaise(ffi.NULL)

    def get_listener_bf(self):
        _ret_c = lib.cw__foo_listener_bf_get_listener_bf(self._cpp_impl)
        CPyException.toPyCheckAndRaise(_ret_c)
        _ret = FooListenerBfHelper.toPy(_ret_c)
        assert _ret is not None
        return _ret

    def set_binary(self, b):
        with CPyBinary.fromPy(b) as pybin_b:
            lib.cw__foo_listener_bf_set_binary(self._cpp_impl, pybin_b.release_djinni_binary())
            CPyException.toPyCheckAndRaise(ffi.NULL)

    def get_binary(self):
        _ret_c = lib.cw__foo_listener_bf_get_binary(self._cpp_impl)
        CPyException.toPyCheckAndRaise(_ret_c)
        _ret = CPyBinary.toPy(_ret_c)
        assert _ret is not None
        return _ret

    def send_return(self, fl_bf):
        _ret_c = lib.cw__foo_listener_bf_send_return(self._cpp_impl, FooListenerBfHelper.fromPy(fl_bf))
        CPyException.toPyCheckAndRaise(_ret_c)
        _ret = FooListenerBfHelper.toPy(_ret_c)
        assert _ret is not None
        return _ret

    def delete_fl_in_fl(self):
        lib.cw__foo_listener_bf_delete_fl_in_fl(self._cpp_impl)
        CPyException.toPyCheckAndRaise(ffi.NULL)

class FooListenerBfCallbacksHelper():
    @ffi.callback("struct DjinniString *(struct DjinniObjectHandle * , struct DjinniString *)")
    def on_string_change(cself, private_string):
        try:
            with CPyString.fromPy(FooListenerBfHelper.selfToPy(cself).on_string_change(CPyString.toPy(private_string))) as py_obj:
                _ret = py_obj.release_djinni_string()
                assert _ret != ffi.NULL
                return _ret
        except Exception as _djinni_py_e:
            CPyException.setExceptionFromPy(_djinni_py_e)
            return ffi.NULL

    @ffi.callback("struct DjinniString *(struct DjinniObjectHandle * )")
    def get_string(cself):
        try:
            with CPyString.fromPy(FooListenerBfHelper.selfToPy(cself).get_string()) as py_obj:
                _ret = py_obj.release_djinni_string()
                assert _ret != ffi.NULL
                return _ret
        except Exception as _djinni_py_e:
            CPyException.setExceptionFromPy(_djinni_py_e)
            return ffi.NULL

    @ffi.callback("struct DjinniWrapperFooListenerBf *(struct DjinniObjectHandle * )")
    def create():
        try:
            _ret = FooListenerBfHelper.fromPy(FooListenerBfHelper.selfToPy(cself).create())
            assert _ret != ffi.NULL
            return _ret
        except Exception as _djinni_py_e:
            CPyException.setExceptionFromPy(_djinni_py_e)
            return ffi.NULL

    @ffi.callback("void(struct DjinniObjectHandle * , struct DjinniWrapperFooListenerBf *)")
    def set_listener_bf(cself, listener):
        try:
            FooListenerBfHelper.selfToPy(cself).set_listener_bf(FooListenerBfHelper.toPy(listener))
        except Exception as _djinni_py_e:
            CPyException.setExceptionFromPy(_djinni_py_e)

    @ffi.callback("struct DjinniWrapperFooListenerBf *(struct DjinniObjectHandle * )")
    def get_listener_bf(cself):
        try:
            _ret = FooListenerBfHelper.fromPy(FooListenerBfHelper.selfToPy(cself).get_listener_bf())
            assert _ret != ffi.NULL
            return _ret
        except Exception as _djinni_py_e:
            CPyException.setExceptionFromPy(_djinni_py_e)
            return ffi.NULL

    @ffi.callback("void(struct DjinniObjectHandle * , struct DjinniBinary *)")
    def set_binary(cself, b):
        try:
            FooListenerBfHelper.selfToPy(cself).set_binary(CPyBinary.toPy(b))
        except Exception as _djinni_py_e:
            CPyException.setExceptionFromPy(_djinni_py_e)

    @ffi.callback("struct DjinniBinary *(struct DjinniObjectHandle * )")
    def get_binary(cself):
        try:
            with CPyBinary.fromPy(FooListenerBfHelper.selfToPy(cself).get_binary()) as py_obj:
                _ret = py_obj.release_djinni_binary()
                assert _ret != ffi.NULL
                return _ret
        except Exception as _djinni_py_e:
            CPyException.setExceptionFromPy(_djinni_py_e)
            return ffi.NULL

    @ffi.callback("struct DjinniWrapperFooListenerBf *(struct DjinniObjectHandle * , struct DjinniWrapperFooListenerBf *)")
    def send_return(cself, fl_bf):
        try:
            _ret = FooListenerBfHelper.fromPy(FooListenerBfHelper.selfToPy(cself).send_return(FooListenerBfHelper.toPy(fl_bf)))
            assert _ret != ffi.NULL
            return _ret
        except Exception as _djinni_py_e:
            CPyException.setExceptionFromPy(_djinni_py_e)
            return ffi.NULL

    @ffi.callback("void(struct DjinniObjectHandle * )")
    def delete_fl_in_fl(cself):
        try:
            FooListenerBfHelper.selfToPy(cself).delete_fl_in_fl()
        except Exception as _djinni_py_e:
            CPyException.setExceptionFromPy(_djinni_py_e)

    @ffi.callback("void(struct DjinniObjectHandle * )")
    def __delete(c_ptr):
        assert c_ptr in FooListenerBfHelper.c_data_set
        FooListenerBfHelper.c_data_set.remove(c_ptr)

    @staticmethod
    def _add_callbacks():
        lib.foo_listener_bf_add_callback_on_string_change(FooListenerBfCallbacksHelper.on_string_change)
        lib.foo_listener_bf_add_callback_get_string(FooListenerBfCallbacksHelper.get_string)
        lib.foo_listener_bf_add_callback_create(FooListenerBfCallbacksHelper.create)
        lib.foo_listener_bf_add_callback_set_listener_bf(FooListenerBfCallbacksHelper.set_listener_bf)
        lib.foo_listener_bf_add_callback_get_listener_bf(FooListenerBfCallbacksHelper.get_listener_bf)
        lib.foo_listener_bf_add_callback_set_binary(FooListenerBfCallbacksHelper.set_binary)
        lib.foo_listener_bf_add_callback_get_binary(FooListenerBfCallbacksHelper.get_binary)
        lib.foo_listener_bf_add_callback_send_return(FooListenerBfCallbacksHelper.send_return)
        lib.foo_listener_bf_add_callback_delete_fl_in_fl(FooListenerBfCallbacksHelper.delete_fl_in_fl)

        lib.foo_listener_bf_add_callback___delete(FooListenerBfCallbacksHelper.__delete)

FooListenerBfCallbacksHelper._add_callbacks()

class FooListenerBfHelper:
    c_data_set = MultiSet()
    @staticmethod
    def toPy(obj):
        if obj == ffi.NULL:
            return None
        # Python Objects can be returned without being wrapped in proxies
        py_handle = lib.get_handle_from_proxy_object_cw__foo_listener_bf(obj)
        if py_handle:
            assert py_handle in FooListenerBfHelper.c_data_set
            aux = ffi.from_handle(ffi.cast("void * ", py_handle))
            lib.foo_listener_bf___wrapper_dec_ref(obj)
            return aux
        return FooListenerBfCppProxy(obj)

    @staticmethod
    def selfToPy(obj):
        assert obj in FooListenerBfHelper.c_data_set
        return ffi.from_handle(ffi.cast("void * ",obj))

    @staticmethod
    def fromPy(py_obj):
        if py_obj is None:
            return ffi.NULL
        if isinstance(py_obj, FooListenerBfCppProxy):
            lib.foo_listener_bf___wrapper_add_ref(py_obj._cpp_impl)
            return py_obj._cpp_impl

        py_proxy = (py_obj)
        if not hasattr(py_obj, "on_string_change"):
            raise TypeError
        if not hasattr(py_obj, "get_string"):
            raise TypeError
        if not hasattr(py_obj, "create"):
            raise TypeError
        if not hasattr(py_obj, "set_listener_bf"):
            raise TypeError
        if not hasattr(py_obj, "get_listener_bf"):
            raise TypeError
        if not hasattr(py_obj, "set_binary"):
            raise TypeError
        if not hasattr(py_obj, "get_binary"):
            raise TypeError
        if not hasattr(py_obj, "send_return"):
            raise TypeError
        if not hasattr(py_obj, "delete_fl_in_fl"):
            raise TypeError

        bare_c_ptr = ffi.new_handle(py_proxy)
        FooListenerBfHelper.c_data_set.add(bare_c_ptr)
        wrapped_c_ptr = lib.make_proxy_object_from_handle_cw__foo_listener_bf(bare_c_ptr)
        return wrapped_c_ptr
