use crate::{GCDatapointID, GCDatapointValue, GCDatapointValueQuality};
use gc_abi::{GCEthernetInterface, GCSerialInterface, raw};
use log::{debug, error, info, warn};
use std::{ffi::CStr, os::raw::c_uint};
pub type PublishDatapointValueIntercept = dyn Fn(&GCDatapointValue) -> bool;
pub type LogIntercept = dyn Fn(c_uint, &CStr);
pub type GetLastDatapointValueIntercept = dyn Fn(GCDatapointID) -> GCDatapointValue;
pub type GetEthernetInterfaceIntercept = dyn Fn(&CStr) -> Option<GCEthernetInterface>;
pub type GetSerialInterfaceIntercept = dyn Fn(&CStr) -> Option<GCSerialInterface>;
pub struct GCGatewayMockInstanceCtx {
pub(super) publish_datapoint_callback: Box<PublishDatapointValueIntercept>,
pub(super) log_callback: Box<LogIntercept>,
pub(super) get_last_datapoint_callback: Box<GetLastDatapointValueIntercept>,
pub(super) get_ethernet_interface_callback: Box<GetEthernetInterfaceIntercept>,
pub(super) get_serial_interface_callback: Box<GetSerialInterfaceIntercept>,
}
impl GCGatewayMockInstanceCtx {
pub fn new() -> Box<Self> {
Box::new(Self {
publish_datapoint_callback: Box::new(|_| true),
log_callback: Box::new(|log_level, line| {
let log_converted = line.to_string_lossy();
match log_level {
raw::eGCLogLevel_CRITICAL => error!("[PLUGIN] {log_converted}"),
raw::eGCLogLevel_ERROR => error!("[PLUGIN] {log_converted}"),
raw::eGCLogLevel_WARNING => warn!("[PLUGIN] {log_converted}"),
raw::eGCLogLevel_INFO => info!("[PLUGIN] {log_converted}"),
raw::eGCLogLevel_DEBUG => debug!("[PLUGIN] {log_converted}"),
level => error!("Log level={level} is not implemented in core"),
}
}),
get_last_datapoint_callback: Box::new(|datapoint| {
GCDatapointValue::new_boolean(datapoint, 0, false, GCDatapointValueQuality::new_good())
}),
get_ethernet_interface_callback: Box::new(|_| None),
get_serial_interface_callback: Box::new(|_| None),
})
}
}
impl From<raw::GCCoreCtx> for &GCGatewayMockInstanceCtx {
fn from(ctx: raw::GCCoreCtx) -> Self {
let a = ctx as *mut GCGatewayMockInstanceCtx;
unsafe { &*a }
}
}