/* Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
#include "l_sml_adapter.h"
#include "pd_log_process.h"
#include "pd_log_adapter.h"

namespace sml {
static void *g_sml_base = nullptr;
static void *g_log_base = nullptr;
static SML_ADAPTER_S *g_sml_adapter = nullptr;
static PD_LOG_PARSE *g_pd_log_parse = nullptr;
static PD_LOG_ADAPTER_S *g_pd_log_adapter = nullptr;

guint8 VENDER_OTHER = 0;
guint8 VENDER_HISOTRE = 1;
guint8 VENDER_INVALID = 255;
guint8 PMC_2100_8I_SMART_HBA = 65;
guint8 HI1880_SP186_M_16i = 96;
guint8 HI1880_SP186_M_8i = 113;
#ifdef BUILD_SML_OPEN
    const char* SML_BASE_LIB_PATH = "/usr/lib64/libsml_base_open.so";
    const char* SML_CUSTOM_BASE_LIB_PATH = "/usr/lib64/libsml_custom_base_open.so";
    const char* SML_PD_LOG_PARSE_PATH = "/usr/lib64/libpd_log_parse_open.so";
#else
    const char* SML_BASE_LIB_PATH = "/usr/lib64/libsml_base.so";
    const char* SML_CUSTOM_BASE_LIB_PATH = "/usr/lib64/libsml_custom_base.so";
    const char* SML_PD_LOG_PARSE_PATH = "/usr/lib64/libpd_log_parse.so";
#endif

static const char *get_sml_base_lib_path(guint8 type_id)
{
    if (type_id <= PMC_2100_8I_SMART_HBA) {
        return SML_CUSTOM_BASE_LIB_PATH;
    }

    if (type_id >= HI1880_SP186_M_16i and type_id <= HI1880_SP186_M_8i) {
        return SML_BASE_LIB_PATH;
    }
    return nullptr;
}

static void register_sml_adapter_fun(const char *sml_base_lib_path, SML_ADAPTER_FUNC_S *sml_adapter_fun_table,
    guint8 num)
{
    if (g_sml_base == nullptr) {
        g_sml_base = dlopen(sml_base_lib_path, RTLD_LAZY);
        if (g_sml_base == nullptr) {
            debug_log(DLOG_ERROR, "dlopen %s failed %s", sml_base_lib_path, dlerror());
            return;
        }
    }

    guint8 i;
    for (i = 0; i < num; i++) {
        *(sml_adapter_fun_table[i].pfunc) = dlsym(g_sml_base, sml_adapter_fun_table[i].func_name);
        if (*(sml_adapter_fun_table[i].pfunc) == nullptr) {
            debug_log(DLOG_ERROR, "Unable to get Entry Point function address-%s", sml_adapter_fun_table[i].func_name);
        }
    }
    return;
}

static void register_pd_log_parse()
{
    if (g_sml_base == nullptr) {
        return;
    }
    if (g_pd_log_parse != nullptr) {
        debug_log(DLOG_ERROR, "%s: g_pd_log_parse is already generate", __FUNCTION__);
        return;
    }

    if (g_pd_log_parse == nullptr) {
        g_pd_log_parse = (PD_LOG_PARSE *)g_malloc0(sizeof(PD_LOG_PARSE));
    }

    PD_LOG_PARSE_FUNC_S pd_log_parse_fun_table[] = {
        { (void **)&g_pd_log_parse->sml_get_pd_log, "sml_get_pd_log"},
        { (void **)&g_pd_log_parse->sml_get_ata_smart_attr_name, "sml_get_ata_smart_attr_name"},
        { (void **)&g_pd_log_parse->sml_parse_ata_smart_attr_raw_value, "sml_parse_ata_smart_attr_raw_value"}
    };

    guint8 i;
    for (i = 0; i < G_N_ELEMENTS(pd_log_parse_fun_table); i++) {
        *(pd_log_parse_fun_table[i].pfunc) = dlsym(g_sml_base, pd_log_parse_fun_table[i].func_name);
        if (*(pd_log_parse_fun_table[i].pfunc) == nullptr) {
            debug_log(DLOG_ERROR, "Unable to get Entry Point function address-%s", pd_log_parse_fun_table[i].func_name);
            goto ERROR;
        }
    }
    pd_log_adapter::adapter_save_pd_log_parse_fun_table(&g_pd_log_parse);
    return;
ERROR:
    for (i = 0; i < G_N_ELEMENTS(pd_log_parse_fun_table); i++) {
        *(pd_log_parse_fun_table[i].pfunc) = nullptr;
    }
    g_free(g_pd_log_parse);
    g_pd_log_parse = nullptr;
    return;
}


static void register_sml_adapter_functions(const char *sml_base_lib_path)
{
    SML_ADAPTER_FUNC_S sml_adapter_fun_table[] = {
        { (void **)(&g_sml_adapter->sml_register_controller), "sml_register_controller"},
        { (void **)(&g_sml_adapter->smlib_get_array_info), "smlib_get_array_info"},
        { (void **)(&g_sml_adapter->sml_unregister_controller), "sml_unregister_controller"},
        { (void **)(&g_sml_adapter->smlib_get_ctrl_info), "smlib_get_ctrl_info"},
        { (void **)(&g_sml_adapter->sml_get_ctrl_pd_list), "sml_get_ctrl_pd_list"},
        { (void **)(&g_sml_adapter->sml_get_ctrl_ld_list), "sml_get_ctrl_ld_list"},
        { (void **)(&g_sml_adapter->sml_get_ctrl_array_list), "sml_get_ctrl_array_list"},
        { (void **)(&g_sml_adapter->sml_get_ctrl_boot_devices), "sml_get_ctrl_boot_devices"},
        { (void **)(&g_sml_adapter->sml_get_ctrl_sas_addr), "sml_get_ctrl_sas_addr"},
        { (void **)(&g_sml_adapter->sml_ctrl_operation), "sml_ctrl_operation"},
        { (void **)(&g_sml_adapter->sml_get_ctrl_health_status), "sml_get_ctrl_health_status"},
        { (void **)(&g_sml_adapter->sml_dump_ctrl_single_log), "sml_dump_ctrl_single_log"},
        { (void **)(&g_sml_adapter->sml_parse_controller_bin_log), "sml_parse_controller_bin_log"},
        { (void **)(&g_sml_adapter->smlib_get_ctrl_bbu_status), "smlib_get_ctrl_bbu_status"},
        { (void **)(&g_sml_adapter->smlib_get_ld_info), "smlib_get_ld_info"},
        { (void **)(&g_sml_adapter->smlib_exec_ld_operation), "smlib_exec_ld_operation"},
        { (void **)(&g_sml_adapter->sml_set_ld_boot_priority), "sml_set_ld_boot_priority"},
        { (void **)(&g_sml_adapter->sml_set_ld_delete), "sml_set_ld_delete"},
        { (void **)(&g_sml_adapter->sml_create_ld_on_existed_array), "sml_create_ld_on_existed_array"},
        { (void **)(&g_sml_adapter->sml_create_ld_on_new_array), "sml_create_ld_on_new_array"},
        { (void **)(&g_sml_adapter->sml_get_ld_sscd_caching_enable), "sml_get_ld_sscd_caching_enable"},
        { (void **)(&g_sml_adapter->sml_get_sscd_associated_ld_list), "sml_get_sscd_associated_ld_list"},
        { (void **)(&g_sml_adapter->sml_get_ld_associated_sscd_list), "sml_get_ld_associated_sscd_list"},
        { (void **)(&g_sml_adapter->sml_set_ld_cachecade_association),
            "sml_set_ld_cachecade_association"},
        { (void **)(&g_sml_adapter->sml_create_ld_as_cachecade), "sml_create_ld_as_cachecade"},
        { (void **)(&g_sml_adapter->smlib_get_pd_info), "smlib_get_pd_info"},
        { (void **)(&g_sml_adapter->smlib_get_pd_sas_smart_info), "smlib_get_pd_sas_smart_info"},
        { (void **)(&g_sml_adapter->smlib_get_pd_sas_smart_info_spec),
            "smlib_get_pd_sas_smart_info_spec"},
        { (void **)(&g_sml_adapter->smlib_get_pd_slow_disk_info), "smlib_get_pd_slow_disk_info"},
        { (void **)(&g_sml_adapter->sml_pd_operation), "sml_pd_operation"},
        { (void **)(&g_sml_adapter->sml_diagnose_encl_comm_error), "sml_diagnose_encl_comm_error"},
        { (void **)(&g_sml_adapter->sml_diagnose_pd_sense_error), "sml_diagnose_pd_sense_error"},
        { (void **)(&g_sml_adapter->sml_get_smart_data_str), "sml_get_smart_data_str"},
        { (void **)(&g_sml_adapter->smlib_diagnose_link_phy_error), "smlib_diagnose_link_phy_error"},
        { (void **)(&g_sml_adapter->sml_get_ctrl_exp_sas_phy_err_count),
            "sml_get_ctrl_exp_sas_phy_err_count"},
        { (void **)(&g_sml_adapter->smlib_get_ctrl_phy_err_count), "smlib_get_ctrl_phy_err_count"},
        { (void **)(&g_sml_adapter->sml_clear_all_controller_info), "sml_clear_all_controller_info"},
        { (void **)(&g_sml_adapter->sml_get_ctrl_init_state), "sml_get_ctrl_init_state"},
        { (void **)(&g_sml_adapter->sml_pd_trans_drive_data), "sml_pd_trans_drive_data"}
    };

    register_sml_adapter_fun(sml_base_lib_path, sml_adapter_fun_table, G_N_ELEMENTS(sml_adapter_fun_table));
    return;
}

static void register_sml_adapter_fun_table(const char *sml_base_lib_path)
{
    if (g_sml_adapter != nullptr) {
        debug_log(DLOG_ERROR, "%s: g_sml_adapter is already generate", __FUNCTION__);
        return;
    }

    if (g_sml_adapter == nullptr) {
        g_sml_adapter = (SML_ADAPTER_S *)g_malloc0(sizeof(SML_ADAPTER_S));
    }

    register_sml_adapter_functions(sml_base_lib_path);
}

static void register_pd_log_parse_table()
{
    if (g_log_base == nullptr) {
        g_log_base = dlopen(SML_PD_LOG_PARSE_PATH, RTLD_LAZY);
        if (g_log_base == nullptr) {
            debug_log(DLOG_ERROR, "dlopen %s failed %s", SML_PD_LOG_PARSE_PATH, dlerror());
            return;
        }
    }

    if (g_pd_log_adapter != nullptr) {
        debug_log(DLOG_ERROR, "%s: g_pd_log_adapter is already generate", __FUNCTION__);
        return;
    }

    if (g_pd_log_adapter == nullptr) {
        g_pd_log_adapter = (PD_LOG_ADAPTER_S *)g_malloc0(sizeof(PD_LOG_ADAPTER_S));
    }

    PD_LOG_PARSE_FUNC_S pd_log_table[] = {
        { (void **)&g_pd_log_adapter->io_deterioration_handle_basic_data, "io_deterioration_handle_basic_data"},
        { (void **)&g_pd_log_adapter->io_deterioration_handle_data, "io_deterioration_handle_data"},
        { (void **)&g_pd_log_adapter->pd_log_collect_raw_data_from_oob, "pd_log_collect_raw_data_from_oob"},
        { (void **)&g_pd_log_adapter->pd_log_clear_data, "pd_log_clear_data"},
        { (void **)&g_pd_log_adapter->pd_log_collect_sas_from_oob, "pd_log_collect_sas_from_oob"},
        { (void **)&g_pd_log_adapter->pd_log_handle_sas, "pd_log_handle_sas"},
        { (void **)&g_pd_log_adapter->pd_log_handle_sata_smart, "pd_log_handle_sata_smart"},
        { (void **)&g_pd_log_adapter->pd_log_handle_sata_ext_error, "pd_log_handle_sata_ext_error"},
        { (void **)&g_pd_log_adapter->pd_log_handle_sata_ext_self_test, "pd_log_handle_sata_ext_self_test"},
        { (void **)&g_pd_log_adapter->pd_log_handle_sata, "pd_log_handle_sata"},
        { (void **)&g_pd_log_adapter->pd_log_collect_sata_from_oob, "pd_log_collect_sata_from_oob"},
        { (void **)&g_pd_log_adapter->calc_and_save_write_amp_value_by_smart_info,
            "calc_and_save_write_amp_value_by_smart_info"},
        { (void **)&g_pd_log_adapter->save_pd_log_parse_fun_table, "save_pd_log_parse_fun_table"},
        { (void **)&g_pd_log_adapter->pd_log_collect_write_io_latency_from_oob,
            "pd_log_collect_write_io_latency_from_oob"},
        { (void **)&g_pd_log_adapter->pd_log_collect_read_io_latency_from_oob,
            "pd_log_collect_read_io_latency_from_oob"}
    };

    for (guint8 i = 0; i < G_N_ELEMENTS(pd_log_table); i++) {
        *(pd_log_table[i].pfunc) = dlsym(g_log_base, pd_log_table[i].func_name);
        if (*(pd_log_table[i].pfunc) == nullptr) {
            debug_log(DLOG_ERROR, "Unable to get Entry Point function address-%s", pd_log_table[i].func_name);
            goto ERROR;
        }
    }

    return;

ERROR:
    dlclose(g_log_base);
    g_log_base = nullptr;
    for (guint8 i = 0; i < G_N_ELEMENTS(pd_log_table); i++) {
        *(pd_log_table[i].pfunc) = nullptr;
    }
    g_free(g_pd_log_adapter);
    g_pd_log_adapter = nullptr;
}

void l_sml_adapter::register_sml_adapter_function(SML_CTRL_OOB_INFO_S *ctrl)
{
    if (ctrl == nullptr) {
        debug_log(DLOG_ERROR, "%s: ctrl is nullptr", __FUNCTION__);
        return;
    }

    const char *sml_base_lib_path = get_sml_base_lib_path(ctrl->i_controller_typeid);
    if (sml_base_lib_path == nullptr) {
        debug_log(DLOG_ERROR, "%s: sml base lib path is invalid", __FUNCTION__);
        return;
    }
    debug_log(DLOG_NOTICE, "%s: controller type id is %u", __FUNCTION__, ctrl->i_controller_typeid);
    register_sml_adapter_fun_table(sml_base_lib_path);
    register_pd_log_parse_table();
    register_pd_log_parse();
    return;
}

gint32 l_sml_adapter::sml_adapter_register_controller(SML_CTRL_OOB_INFO_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_register_controller != nullptr) {
        return g_sml_adapter->sml_register_controller(ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_array_info(guint8 ctrl_index, guint16 array_ref, SML_ARRAY_INFO_S *array)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_get_array_info != nullptr) {
        return g_sml_adapter->smlib_get_array_info(ctrl_index, array_ref, array);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_unregister_controller(SML_CTRL_OOB_INFO_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_unregister_controller != nullptr) {
        return g_sml_adapter->sml_unregister_controller(ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_info(guint8 ctrl_index, SML_CTRL_BASIC_INFO_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_get_ctrl_info != nullptr) {
        return g_sml_adapter->smlib_get_ctrl_info(ctrl_index, ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_pd_list(SML_CTRL_PD_LIST_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ctrl_pd_list != nullptr) {
        return g_sml_adapter->sml_get_ctrl_pd_list(ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_ld_list(SML_CTRL_LD_LIST_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ctrl_ld_list != nullptr) {
        return g_sml_adapter->sml_get_ctrl_ld_list(ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_array_list(SML_CTRL_ARRAY_LIST_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ctrl_array_list != nullptr) {
        return g_sml_adapter->sml_get_ctrl_array_list(ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_boot_devices(SML_CTRL_BOOTABLE_DEVICES_S *boot_devices)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ctrl_boot_devices != nullptr) {
        return g_sml_adapter->sml_get_ctrl_boot_devices(boot_devices);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_sas_addr(SML_CTRL_SAS_ADDR_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ctrl_sas_addr != nullptr) {
        return g_sml_adapter->sml_get_ctrl_sas_addr(ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_ctrl_operation(SML_CTRL_OPERTATION_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_ctrl_operation != nullptr) {
        return g_sml_adapter->sml_ctrl_operation(ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_health_status(SML_CTRL_HEALTH_STATUS_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ctrl_health_status != nullptr) {
        return g_sml_adapter->sml_get_ctrl_health_status(ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_dump_ctrl_single_log(guint8 ctrl_id, const gchar *src_dir,
    guint8 log_type, const gchar *log_name)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_dump_ctrl_single_log != nullptr) {
        return g_sml_adapter->sml_dump_ctrl_single_log(ctrl_id, src_dir, log_type, log_name);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_parse_controller_bin_log(guint8 ctrl_id, const gchar *src_dir, const gchar *dest_dir)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_parse_controller_bin_log != nullptr) {
        return g_sml_adapter->sml_parse_controller_bin_log(ctrl_id, src_dir, dest_dir);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_bbu_status(guint8 ctrl_index, SML_BBU_STATUS_S *ctrl)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_get_ctrl_bbu_status != nullptr) {
        return g_sml_adapter->smlib_get_ctrl_bbu_status(ctrl_index, ctrl);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ld_info(guint8 ctrl_index, guint16 ld_target_id, SML_LD_BASIC_INFO_S *ld)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_get_ld_info != nullptr) {
        return g_sml_adapter->smlib_get_ld_info(ctrl_index, ld_target_id, ld);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_exec_ld_operation(guint8 ctrl_index, guint16 ld_target_id,
    guint8 operation, gpointer param, guint32 param_length)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_exec_ld_operation != nullptr) {
        return g_sml_adapter->smlib_exec_ld_operation(ctrl_index, ld_target_id, operation, param, param_length);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_set_ld_boot_priority(SML_LD_TARGET_S *ld)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_set_ld_boot_priority != nullptr) {
        return g_sml_adapter->sml_set_ld_boot_priority(ld);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_set_ld_delete(SML_LD_TARGET_S *ld)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_set_ld_delete != nullptr) {
        return g_sml_adapter->sml_set_ld_delete(ld);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_create_ld_on_existed_array(SML_RAID_ON_EXISTED_ARRAY_PARAM_S *config)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_create_ld_on_existed_array != nullptr) {
        return g_sml_adapter->sml_create_ld_on_existed_array(config);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_create_ld_on_new_array(SML_RAID_ON_NEW_ARRAY_PARAM_S *config)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_create_ld_on_new_array != nullptr) {
        return g_sml_adapter->sml_create_ld_on_new_array(config);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ld_sscd_caching_enable(SML_LD_SSCD_CACHING_ENABLE_S *ld)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ld_sscd_caching_enable != nullptr) {
        return g_sml_adapter->sml_get_ld_sscd_caching_enable(ld);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_sscd_associated_ld_list(SML_SSCD_ASSOCIATED_LD_LIST_S *ld)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_sscd_associated_ld_list != nullptr) {
        return g_sml_adapter->sml_get_sscd_associated_ld_list(ld);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ld_associated_sscd_list(SML_LD_ASSOCIATED_SSCD_LIST_S *ld)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ld_associated_sscd_list != nullptr) {
        return g_sml_adapter->sml_get_ld_associated_sscd_list(ld);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_set_ld_cachecade_association(SML_LD_SET_CACHECADE_ASSOCIATION_S *ld)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_set_ld_cachecade_association != nullptr) {
        return g_sml_adapter->sml_set_ld_cachecade_association(ld);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_create_ld_as_cachecade(SML_RAID_CACHECADE_PARAM_S *config)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_create_ld_as_cachecade != nullptr) {
        return g_sml_adapter->sml_create_ld_as_cachecade(config);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_pd_info(guint8 ctrl_index, guint16 pd_device_id, SML_PD_BASIC_INFO_S *pd)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_get_pd_info != nullptr) {
        return g_sml_adapter->smlib_get_pd_info(ctrl_index, pd_device_id, pd);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_pd_sas_smart_info(guint8 ctrl_index, guint16 pd_device_id,
    SML_PD_SAS_SMART_INFO *smart_info)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_get_pd_sas_smart_info != nullptr) {
        return g_sml_adapter->smlib_get_pd_sas_smart_info(ctrl_index, pd_device_id, smart_info);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_pd_sas_smart_info_spec(guint8 ctrl_index, guint16 pd_device_id,
    SML_PD_SAS_SMART_INFO *smart_info, guint8 filter)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_get_pd_sas_smart_info_spec != nullptr) {
        return g_sml_adapter->smlib_get_pd_sas_smart_info_spec(ctrl_index, pd_device_id, smart_info, filter);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_pd_slow_disk_info(guint8 ctrl_index, guint16 pd_device_id,
    void *slow_disk_info)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_get_pd_slow_disk_info != nullptr) {
        return g_sml_adapter->smlib_get_pd_slow_disk_info(ctrl_index, pd_device_id, (void *)slow_disk_info);
    }
    return SML_ERR_NULL_INFTERFACE;
}

gint32 l_sml_adapter::sml_adapter_pd_operation(SML_PD_OPERTATION_S *pd)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_pd_operation != nullptr) {
        return g_sml_adapter->sml_pd_operation(pd);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_diagnose_encl_comm_error(SML_PD_FAULT_ANALYSIS *diag_info)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_diagnose_encl_comm_error != nullptr) {
        return g_sml_adapter->sml_diagnose_encl_comm_error(diag_info);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_diagnose_pd_sense_error(SML_PD_FAULT_ANALYSIS* diag_info)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_diagnose_pd_sense_error != nullptr) {
        return g_sml_adapter->sml_diagnose_pd_sense_error(diag_info);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_smart_data_str(guint8 controller_index, guint16 pd_device_id,
    guint8 hdd_intf_type, GVariant **smart_info_var)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_smart_data_str != nullptr) {
        return g_sml_adapter->sml_get_smart_data_str(controller_index, pd_device_id, hdd_intf_type, smart_info_var);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_diagnose_link_phy_error(SML_PD_FAULT_ANALYSIS *diag_info, guint32 serial_threshold,
    guint32 recent_threshold)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_diagnose_link_phy_error != nullptr) {
        return g_sml_adapter->smlib_diagnose_link_phy_error(diag_info, serial_threshold, recent_threshold);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_exp_sas_phy_err_count(SML_CTRL_EXP_SAS_PHY_INFO_S *expander)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ctrl_exp_sas_phy_err_count != nullptr) {
        return g_sml_adapter->sml_get_ctrl_exp_sas_phy_err_count(expander);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_get_ctrl_phy_err_count(guint8 ctrl_index, SML_SASPHY_INFO_S *ctrl,
    guint8 force_update)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->smlib_get_ctrl_phy_err_count != nullptr) {
        return g_sml_adapter->smlib_get_ctrl_phy_err_count(ctrl_index, ctrl, force_update);
    }
    return 0;
}

void l_sml_adapter::sml_adapter_clear_all_controller_info(void)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_clear_all_controller_info != nullptr) {
        g_sml_adapter->sml_clear_all_controller_info();
    }
}

gint8 l_sml_adapter::sml_adapter_get_ctrl_init_state(guint8 ctrl_index)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_get_ctrl_init_state != nullptr) {
        return g_sml_adapter->sml_get_ctrl_init_state(ctrl_index);
    }
    return 0;
}

gint32 l_sml_adapter::sml_adapter_pd_trans_drive_data(guint8 ctrl_id, const gchar *json_raw_data)
{
    if (g_sml_adapter != nullptr && g_sml_adapter->sml_pd_trans_drive_data != nullptr) {
        return g_sml_adapter->sml_pd_trans_drive_data(ctrl_id, json_raw_data);
    }
    return 0;
}

void pd_log_adapter::adapter_io_deterioration_handle_basic_data(PD_LOG_S *pd_log, Json *pd_io_info_jso)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->io_deterioration_handle_basic_data != nullptr) {
        g_pd_log_adapter->io_deterioration_handle_basic_data(pd_log, pd_io_info_jso);
    }
}

void pd_log_adapter::adapter_io_deterioration_handle_data(PD_LOG_S *pd_log, Json *pd_io_info_jso)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->io_deterioration_handle_data != nullptr) {
        g_pd_log_adapter->io_deterioration_handle_data(pd_log, pd_io_info_jso);
    }
}

void pd_log_adapter::adapter_pd_log_collect_raw_data_from_oob(guint8 ctrl_index, guint16 pd_device_id,
    SML_PD_LOG_DATA_S *pd_log_raw_data, guint32 pd_log_collect_timeout)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_collect_raw_data_from_oob != nullptr) {
        g_pd_log_adapter->pd_log_collect_raw_data_from_oob(ctrl_index, pd_device_id, pd_log_raw_data,
            pd_log_collect_timeout);
    }
}

void pd_log_adapter::adapter_pd_log_clear_data(PD_LOG_S *pd_log)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_clear_data != nullptr) {
        g_pd_log_adapter->pd_log_clear_data(pd_log);
    }
}

gint32 pd_log_adapter::adapter_pd_log_collect_sas_from_oob(guint8 ctrl_index, guint16 pd_device_id, PD_LOG_S *pd_log)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_collect_sas_from_oob != nullptr) {
        return g_pd_log_adapter->pd_log_collect_sas_from_oob(ctrl_index, pd_device_id, pd_log);
    }
    return 1;
}

void pd_log_adapter::adapter_pd_log_handle_sas(PD_LOG_S *pd_log, Json *pd_log_jso)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_handle_sas != nullptr) {
        g_pd_log_adapter->pd_log_handle_sas(pd_log, pd_log_jso);
    }
}

void pd_log_adapter::adapter_pd_log_handle_sata_smart(FILE *file, PD_LOG_S *pd_log, void *out_put)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_handle_sata_smart != nullptr) {
        g_pd_log_adapter->pd_log_handle_sata_smart(file, pd_log, out_put);
    }
}

void pd_log_adapter::adapter_pd_log_handle_sata_ext_error(FILE *file, PD_LOG_S *pd_log, void *out_put,
    Json *pd_log_jso)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_handle_sata_ext_error != nullptr) {
        g_pd_log_adapter->pd_log_handle_sata_ext_error(file, pd_log, out_put, pd_log_jso);
    }
}

void pd_log_adapter::adapter_pd_log_handle_sata_ext_self_test(FILE *file, PD_LOG_S *pd_log,
    void *out_put, Json *pd_log_jso)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_handle_sata_ext_self_test != nullptr) {
        g_pd_log_adapter->pd_log_handle_sata_ext_self_test(file, pd_log, out_put, pd_log_jso);
    }
}

void pd_log_adapter::adapter_pd_log_handle_sata(PD_LOG_S *pd_log, Json *pd_log_jso)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_handle_sata != nullptr) {
        g_pd_log_adapter->pd_log_handle_sata(pd_log, pd_log_jso);
    }
}

gint32 pd_log_adapter::adapter_pd_log_collect_sata_from_oob(guint8 ctrl_index, guint16 pd_device_id, PD_LOG_S *pd_log)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_collect_sata_from_oob != nullptr) {
        return g_pd_log_adapter->pd_log_collect_sata_from_oob(ctrl_index, pd_device_id, pd_log);
    }
    return 1;
}

gint32 pd_log_adapter::adapter_pd_log_collect_write_io_latency_from_oob(guint8 ctrl_index, guint16 pd_device_id,
    PD_DIAGNOSE_INFO *pd_log)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_collect_write_io_latency_from_oob != nullptr) {
        return g_pd_log_adapter->pd_log_collect_write_io_latency_from_oob(ctrl_index, pd_device_id, pd_log);
    }
    return 1;
}

gint32 pd_log_adapter::adapter_pd_log_collect_read_io_latency_from_oob(guint8 ctrl_index, guint16 pd_device_id,
    PD_DIAGNOSE_INFO *pd_log)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->pd_log_collect_read_io_latency_from_oob != nullptr) {
        return g_pd_log_adapter->pd_log_collect_read_io_latency_from_oob(ctrl_index, pd_device_id, pd_log);
    }
    return 1;
}

void pd_log_adapter::adapter_calc_and_save_write_amp_value_by_smart_info(char *device_name, guint32 est_lfsp_value,
    SML_PD_SSD_WRITE_AMP_FACTOR_S *write_amp_info, WRITE_AMP_LAST_INFO_S *write_amp_last_info,
    Json *disk_write_amp_jso)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->calc_and_save_write_amp_value_by_smart_info != nullptr) {
        g_pd_log_adapter->calc_and_save_write_amp_value_by_smart_info(device_name, est_lfsp_value,
            write_amp_info, write_amp_last_info, disk_write_amp_jso);
    }
}

void pd_log_adapter::adapter_save_pd_log_parse_fun_table(PD_LOG_PARSE **pd_log_parse)
{
    if (g_pd_log_adapter != nullptr && g_pd_log_adapter->save_pd_log_parse_fun_table != nullptr) {
        g_pd_log_adapter->save_pd_log_parse_fun_table(pd_log_parse);
    }
}
} // namespace