//! Raw bindings access.
//!
//! This module contains the raw bindings also available in the `gc_abi_sys` crate.
//! A plugin should never use this module directly as it is inherently unsafe.
//!
//! It's exposure is required by the the macros or tests.

pub use gc_abi_sys::*;

// This functions are tested against changes in the underlying abi.h
pub type GCInitPluginExport = unsafe extern "C" fn(init_ctx: gc_abi_sys::GCPluginInterface) -> gc_abi_sys::GCInstanceHandle;
pub type GCShutdownPluginExport = unsafe extern "C" fn(instance: gc_abi_sys::GCInstanceHandle);
pub type GCReceiveDatapointPluginExport =
    unsafe extern "C" fn(instance: gc_abi_sys::GCInstanceHandle, data_value: gc_abi_sys::GCDatapointValue) -> bool;
pub type GCInfoPluginExport = unsafe extern "C" fn() -> gc_abi_sys::GCPluginInfo;

pub type GCSystemLogCoreExport = gc_abi_sys::tSystemLog;
pub type GCSystemLogAuditCoreExport = gc_abi_sys::tAuditLog;
pub type GCReleaseDatapointValueCoreExport = gc_abi_sys::tReleaseDatapointValue;
pub type GCGetLastDatapointValueCoreExport = gc_abi_sys::tGetLastDatapointValue;
pub type GCPublishDatapointValueCoreExport = gc_abi_sys::tPublishDatapointValue;

pub static PLUGIN_START_FUNC_NAME: &str = "gc_plugin_init";
pub static PLUGIN_SHUTDOWN_FUNC_NAME: &str = "gc_plugin_shutdown";
pub static PLUGIN_GET_INFO_FUNC_NAME: &str = "gc_plugin_get_info";
pub static PLUGIN_RECEIVE_DATAPOINT_FUNC_NAME: &str = "gc_plugin_receive_datapoint";

#[cfg(test)]
mod tests {
    use super::*;

    // Once the const type_name is stable, the function names tests can be removed and be used directly as the function names
    fn get_function_name<F>(_: F) -> &'static str {
        let function_full_name = std::any::type_name::<F>();

        (function_full_name.split("::").last().map_or(function_full_name, |name| name)) as _
    }

    #[test]
    fn test_function_names() {
        assert_eq!(PLUGIN_START_FUNC_NAME, get_function_name(gc_abi_sys::gc_plugin_init));
        assert_eq!(PLUGIN_SHUTDOWN_FUNC_NAME, get_function_name(gc_abi_sys::gc_plugin_shutdown));
        assert_eq!(PLUGIN_GET_INFO_FUNC_NAME, get_function_name(gc_abi_sys::gc_plugin_get_info));
        assert_eq!(
            PLUGIN_RECEIVE_DATAPOINT_FUNC_NAME,
            get_function_name(gc_abi_sys::gc_plugin_receive_datapoint)
        );
    }
}
