/* Copyright (c) 2024 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_ld.h"

#include "ld.h"
#include "l_sml_adapter.h"

namespace sml {
static int32_t update_ld_info(lua_State *L, SML_LD_BASIC_INFO_S *info, uint8_t ctrl_index, uint16_t ld_target_id)
{
    if (auto ret = l_sml_adapter::sml_adapter_get_ld_info(ctrl_index, ld_target_id, info); ret != RET_OK) {
        lua_pushinteger(L, ret);
        lua_error(L);
    }
    return 1;
}

static luawrap::n_ret get_ref_array(lua_State *L, SML_LD_BASIC_INFO_S *info)
{
    return push_array(L, info->ref_array, info->array_count);
}

static luawrap::n_ret get_sscd_ld_list(lua_State *L, SML_LD_BASIC_INFO_S *info)
{
    return push_array(L, info->sscd_ld_list, info->sscd_ld_count);
}

static luawrap::n_ret get_spare_pd_ids(lua_State *L, SML_LD_BASIC_INFO_S *info)
{
    return push_array(L, info->spare_pd_ids, info->spare_count);
}

static luawrap::n_ret get_spare_pd_slots(lua_State *L, SML_LD_BASIC_INFO_S *info)
{
    return push_array(L, info->spare_pd_slots, info->spare_count);
}

static luawrap::n_ret get_spare_pd_enclosure_ids(lua_State *L, SML_LD_BASIC_INFO_S *info)
{
    return push_array(L, info->spare_pd_enclosure_ids, info->spare_count);
}

static luawrap::inner_struct_ptr<SML_LD_PROGRESS_INFO_S> get_progress_info(SML_LD_BASIC_INFO_S *p)
{
    return {&p->progress_info};
}

static const char *get_name(SML_LD_BASIC_INFO_S *info)
{
    return info->name;
}

static uint8_t get_current_fgi_state(SML_LD_BASIC_INFO_S *info)
{
    return info->progress_info.current_fgi_state;
}

static uint8_t get_fgi(SML_LD_BASIC_INFO_S *info)
{
    return info->progress_info.fgi;
}

static std::vector<uint16_t> get_ld_ref_array(SML_LD_BASIC_INFO_S *info)
{
    std::vector<uint16_t> result;
    for (guint8 i = 0; i < info->array_count; i++) {
        result.push_back(info->ref_array[i]);
    }
    return result;
}

void l_ld::def_properties(lua_State *L, luawrap::lua_class<SML_LD_BASIC_INFO_S> &cls)
{
    cls.def_readonly("last_update_timestamp", &SML_LD_BASIC_INFO_S::last_update_timestamp);
    cls.def_readonly("ld_warnig_info_reported", &SML_LD_BASIC_INFO_S::ld_warnig_info_reported);
    cls.def_readonly("target_id", &SML_LD_BASIC_INFO_S::target_id);
    cls.def_property("name", c_func_wrap(L, get_name));
    cls.def_readonly("drive_state", &SML_LD_BASIC_INFO_S::drive_state);
    cls.def_readonly("raid_level", &SML_LD_BASIC_INFO_S::raid_level);
    cls.def_readonly("default_read_policy", &SML_LD_BASIC_INFO_S::default_read_policy);
    cls.def_readonly("default_write_policy", &SML_LD_BASIC_INFO_S::default_write_policy);
    cls.def_readonly("default_cache_policy", &SML_LD_BASIC_INFO_S::default_cache_policy);
    cls.def_readonly("current_read_policy", &SML_LD_BASIC_INFO_S::current_read_policy);
    cls.def_readonly("current_write_policy", &SML_LD_BASIC_INFO_S::current_write_policy);
    cls.def_readonly("current_cache_policy", &SML_LD_BASIC_INFO_S::current_cache_policy);
    cls.def_readonly("access_policy", &SML_LD_BASIC_INFO_S::access_policy);
    cls.def_readonly("disk_cache_policy", &SML_LD_BASIC_INFO_S::disk_cache_policy);
    cls.def_readonly("init_state", &SML_LD_BASIC_INFO_S::init_state);
    cls.def_readonly("consistent_check", &SML_LD_BASIC_INFO_S::consistent_check);
    cls.def_readonly("span_depth", &SML_LD_BASIC_INFO_S::span_depth);
    cls.def_readonly("num_drive_per_span", &SML_LD_BASIC_INFO_S::num_drive_per_span);
    cls.def_readonly("bgi_enabled", &SML_LD_BASIC_INFO_S::bgi_enabled);
    cls.def_readonly("bootable", &SML_LD_BASIC_INFO_S::bootable);
    cls.def_readonly("is_sscd", &SML_LD_BASIC_INFO_S::is_sscd);
    cls.def_readonly("is_epd", &SML_LD_BASIC_INFO_S::is_epd);
    cls.def_readonly("strip_size", &SML_LD_BASIC_INFO_S::strip_size);
    cls.def_readonly("accelerator", &SML_LD_BASIC_INFO_S::accelerator);
    cls.def_readonly("size", &SML_LD_BASIC_INFO_S::size);
    cls.def_readonly("max_resizeable_size", &SML_LD_BASIC_INFO_S::max_resizeable_size);
    cls.def_readonly("boot_priority", &SML_LD_BASIC_INFO_S::boot_priority);
    cls.def_readonly("cache_line_size", &SML_LD_BASIC_INFO_S::cache_line_size);
    cls.def_property("ref_array", c_func_wrap(L, get_ref_array));
    cls.def_property("progress_info", c_func_wrap(L, get_progress_info));
    cls.def_property("sscd_ld_list", c_func_wrap(L, get_sscd_ld_list));
    cls.def_property("spare_pd_ids", c_func_wrap(L, get_spare_pd_ids));
    cls.def_property("spare_pd_slots", c_func_wrap(L, get_spare_pd_slots));
    cls.def_property("spare_pd_enclosure_ids", c_func_wrap(L, get_spare_pd_enclosure_ids));
    cls.def_property("ld_ref_array", c_func_wrap(L, get_ld_ref_array));
    cls.def_property("current_fgi_state", c_func_wrap(L, get_current_fgi_state));
    cls.def_property("fgi", c_func_wrap(L, get_fgi));
}

static const char *get_ld_set_props_name(SML_LD_SET_PROPERTIES_S *info)
{
    return info->ld_name;
}

static void set_ld_set_props_name(SML_LD_SET_PROPERTIES_S *info, const char* name)
{
    errno_t securec_rv = strcpy_s(info->ld_name, sizeof(info->ld_name), name);
    if (securec_rv != EOK) {
        debug_log(DLOG_DEBUG, "%s: strcpy_s failed, ret = %d", __FUNCTION__, securec_rv);
    }
}

static int32_t set_ld_info(SML_LD_SET_PROPERTIES_S *info, guint8 ctrl_index, guint16 ld_target_id, guint8 operation)
{
    return l_sml_adapter::sml_adapter_exec_ld_operation(ctrl_index, ld_target_id, operation,
        (gpointer)info, sizeof(SML_LD_SET_PROPERTIES_S));
}

static int32_t start_ld_fgi(SML_LD_SET_PROPERTIES_S *info, guint8 ctrl_index,
    guint16 ld_target_id, guint8 operation, guint8 init_type)
{
    return l_sml_adapter::sml_adapter_exec_ld_operation(ctrl_index, ld_target_id, operation, &init_type, 0);
}

static int32_t cancel_ld_fgi(SML_LD_SET_PROPERTIES_S *info, guint8 ctrl_index, guint16 ld_target_id, guint8 operation)
{
    return l_sml_adapter::sml_adapter_exec_ld_operation(ctrl_index, ld_target_id, operation, nullptr, 0);
}

// 注册逻辑盘设置类属性
void l_ld::def_set_properties(lua_State *L, luawrap::lua_class<SML_LD_SET_PROPERTIES_S> &cls)
{
    cls.def_readwrite("setting_options", &SML_LD_SET_PROPERTIES_S::setting_options);
    cls.def_property("ld_name", c_func_wrap(L, get_ld_set_props_name), c_func_wrap(L, set_ld_set_props_name));
    cls.def_readwrite("read_policy", &SML_LD_SET_PROPERTIES_S::read_policy);
    cls.def_readwrite("write_policy", &SML_LD_SET_PROPERTIES_S::write_policy);
    cls.def_readwrite("io_policy", &SML_LD_SET_PROPERTIES_S::io_policy);
    cls.def_readwrite("access_policy", &SML_LD_SET_PROPERTIES_S::access_policy);
    cls.def_readwrite("disk_cache_policy", &SML_LD_SET_PROPERTIES_S::disk_cache_policy);
    cls.def_readwrite("bgi_enable", &SML_LD_SET_PROPERTIES_S::bgi_enable);
    cls.def_readwrite("accelerator", &SML_LD_SET_PROPERTIES_S::accelerator);
    cls.def_readwrite("capacity", &SML_LD_SET_PROPERTIES_S::capacity);
    cls.def_readwrite("strip_size", &SML_LD_SET_PROPERTIES_S::strip_size);
    cls.def_readwrite("ssd_in_ld", &SML_LD_SET_PROPERTIES_S::ssd_in_ld);
}

static int32_t set_bootable(SML_LD_TARGET_S *info, guint8 boot_priority)
{
    info->i_param_ptr = &boot_priority;
    info->i_param_size = sizeof(boot_priority);
    return l_sml_adapter::sml_adapter_set_ld_boot_priority(info);
}

static int32_t delete_volume(SML_LD_TARGET_S *info)
{
    return l_sml_adapter::sml_adapter_set_ld_delete(info);
}

void l_ld::def_target_properties(lua_State *L, luawrap::lua_class<SML_LD_TARGET_S> &cls)
{
    cls.def_readwrite("i_controller_index", &SML_LD_TARGET_S::i_controller_index);
    cls.def_readwrite("i_target_id", &SML_LD_TARGET_S::i_target_id);
}

// 在已有阵列上创建逻辑盘
static uint16_t exist_array_get_ld_id(SML_RAID_ON_EXISTED_ARRAY_PARAM_S *info)
{
    return info->o_ret_param.ld_target_id;
}

static int32_t add_ld_on_exist_array(SML_RAID_ON_EXISTED_ARRAY_PARAM_S *info, guint8 controller_id, guint16 array_id,
    guint8 block_index, guint8 raid_type, guint8 span_depth, const char* name, guint32 convert_capacity,
    guint8 strip_size, guint8 read_policy, guint8 write_policy, guint8 io_policy, guint8 access_policy,
    guint8 disk_cache_policy, guint8 init_type, guint8 accelerator)
{
    info->i_controller_index = controller_id;
    info->i_array_ref = array_id;
    info->i_block_index = block_index;
    info->i_raid_level = raid_type;
    info->i_span_depth = span_depth;
    info->i_props.capacity = convert_capacity;
    info->i_props.strip_size = strip_size;
    info->i_props.read_policy = read_policy;
    info->i_props.write_policy = write_policy;
    info->i_props.io_policy = io_policy;
    info->i_props.access_policy = access_policy;
    info->i_props.disk_cache_policy = disk_cache_policy;
    info->i_props.init_state = init_type;
    info->i_props.accelerator = accelerator;
    errno_t securec_rv = strcpy_s(info->i_props.ld_name, sizeof(info->i_props.ld_name), name);
    if (securec_rv != EOK) {
        debug_log(DLOG_DEBUG, "%s: strcpy_s failed, ret = %d", __FUNCTION__, securec_rv);
    }
    return l_sml_adapter::sml_adapter_create_ld_on_existed_array(info);
}

// 在新阵列上创建逻辑盘
static uint16_t new_array_get_ld_id(SML_RAID_ON_NEW_ARRAY_PARAM_S *info)
{
    return info->o_ret_param.ld_target_id;
}

static int32_t create_ld_on_new_array(SML_RAID_ON_NEW_ARRAY_PARAM_S *info, guint8 controller_id, guint8 span_depth,
    guint8 drive_count, std::vector<uint16_t> convert_drive_lists, guint32 convert_capacity, guint8 raid_type,
    const char* name, guint8 strip_size, guint8 read_policy, guint8 write_policy, guint8 io_policy,
    guint8 access_policy, guint8 disk_cache_policy, guint8 init_type, guint8 accelerator)
{
    if (convert_drive_lists.size() > SML_MAX_PHYSICAL_DRIVES) {
        debug_log(DLOG_DEBUG, "%s:drive lists out of range", __FUNCTION__);
    }
    info->i_controller_index = controller_id;
    info->i_span_depth = span_depth;
    info->i_num_drive_per_span = drive_count / span_depth;
    for (std::size_t i = 0; i < convert_drive_lists.size(); ++i) {
        info->i_pd_sel[i] = convert_drive_lists[i];
    }
    info->i_props.capacity = convert_capacity;
    info->i_raid_level = raid_type;
    info->i_props.strip_size = strip_size;
    info->i_props.read_policy = read_policy;
    info->i_props.write_policy = write_policy;
    info->i_props.io_policy = io_policy;
    info->i_props.access_policy = access_policy;
    info->i_props.disk_cache_policy = disk_cache_policy;
    info->i_props.init_state = init_type;
    info->i_props.accelerator = accelerator;
    errno_t securec_rv = strcpy_s(info->i_props.ld_name, sizeof(info->i_props.ld_name), name);
    if (securec_rv != EOK) {
        debug_log(DLOG_DEBUG, "%s: strcpy_s failed, ret = %d", __FUNCTION__, securec_rv);
    }
    return l_sml_adapter::sml_adapter_create_ld_on_new_array(info);
}

// 注册普通逻辑盘是否关联到CacheCade逻辑盘属性
void l_ld::def_caching_enable(lua_State *L, luawrap::lua_class<SML_LD_SSCD_CACHING_ENABLE_S> &cls)
{
    cls.def_readwrite("i_controller_index", &SML_LD_SSCD_CACHING_ENABLE_S::i_controller_index);
    cls.def_readwrite("i_target_id", &SML_LD_SSCD_CACHING_ENABLE_S::i_target_id);
    cls.def_readwrite("o_sscd_caching_enable", &SML_LD_SSCD_CACHING_ENABLE_S::o_sscd_caching_enable);
}

static uint32_t get_ld_sscd_caching_enable(lua_State *L, SML_LD_SSCD_CACHING_ENABLE_S *info)
{
    if (auto ret = l_sml_adapter::sml_adapter_get_ld_sscd_caching_enable(info); ret != RET_OK) {
        lua_pushinteger(L, ret);
        lua_error(L);
    }
    return 1;
}

// 注册CacheCade LD关联的逻辑盘列表属性
void l_ld::def_cache_ld(lua_State *L, luawrap::lua_class<SML_SSCD_ASSOCIATED_LD_LIST_S> &cls)
{
    cls.def_readwrite("i_controller_index", &SML_SSCD_ASSOCIATED_LD_LIST_S::i_controller_index);
    cls.def_readwrite("i_sscd_id", &SML_SSCD_ASSOCIATED_LD_LIST_S::i_sscd_id);
    cls.def_readwrite("o_ld_count", &SML_SSCD_ASSOCIATED_LD_LIST_S::o_ld_count);
}

static uint32_t get_sscd_associated_ld_list(lua_State *L, SML_SSCD_ASSOCIATED_LD_LIST_S *info)
{
    if (auto ret = l_sml_adapter::sml_adapter_get_sscd_associated_ld_list(info); ret != RET_OK) {
        lua_pushinteger(L, ret);
        lua_error(L);
    }
    return 1;
}

static std::vector<uint16_t> sscd_associated_ld_list(SML_SSCD_ASSOCIATED_LD_LIST_S *info)
{
    std::vector<uint16_t> result;
    for (guint8 i = 0; i < info->o_ld_count; i++) {
        result.push_back(info->o_ld_ids[i]);
    }
    return result;
}

// 注册逻辑盘关联的CacheCade LD列表属性
void l_ld::def_ld_cache(lua_State *L, luawrap::lua_class<SML_LD_ASSOCIATED_SSCD_LIST_S> &cls)
{
    cls.def_readwrite("i_controller_index", &SML_LD_ASSOCIATED_SSCD_LIST_S::i_controller_index);
    cls.def_readwrite("i_ld_id", &SML_LD_ASSOCIATED_SSCD_LIST_S::i_ld_id);
    cls.def_readwrite("o_sscd_count", &SML_LD_ASSOCIATED_SSCD_LIST_S::o_sscd_count);
}

static uint32_t get_ld_associated_sscd_list(lua_State *L, SML_LD_ASSOCIATED_SSCD_LIST_S *info)
{
    if (auto ret = l_sml_adapter::sml_adapter_get_ld_associated_sscd_list(info); ret != RET_OK) {
        lua_pushinteger(L, ret);
        lua_error(L);
    }
    return 1;
}

static std::vector<uint16_t> ld_associated_sscd_list(SML_LD_ASSOCIATED_SSCD_LIST_S *info)
{
    std::vector<uint16_t> result;
    for (guint8 i = 0; i < info->o_sscd_count; i++) {
        result.push_back(info->o_sscd_ids[i]);
    }
    return result;
}

// SML_LD_SET_CACHECADE_ASSOCIATION_S 类方法
static uint32_t method_set_ld_cachecade(SML_LD_SET_CACHECADE_ASSOCIATION_S *info,
    guint8 ctrl_index, guint16 ld_target_id, guint8 associate)
{
    info->i_controller_index = ctrl_index;
    info->i_target_id = ld_target_id;
    info->i_associate = associate;
    return l_sml_adapter::sml_adapter_set_ld_cachecade_association(info);
}

// SML_RAID_CACHECADE_PARAM_S 类方法
static uint32_t create_ld_as_cachecade(SML_RAID_CACHECADE_PARAM_S *info,
    guint8 ctrl_index, guint32 count, std::vector<uint16_t> drive_lists, guint8 raid_type, guint32 capacity,
    const char* name, guint8 write_policy, guint16 ld_target_id, guint16 associate, guint8 cache_line_size)
{
    info->i_controller_index = ctrl_index;
    info->i_pd_count = count;
    for (guint32 i = 0; i < count; i++) {
        info->i_pd_sel[i] = drive_lists[i];
    }
    info->i_raid_level = raid_type;
    info->i_capacity = capacity;
    info->i_write_policy = write_policy;
    info->i_array_ref = ld_target_id;
    info->i_associated_ld = associate;
    info->i_cache_line_size = cache_line_size;
    errno_t securec_rv = strcpy_s(info->i_ld_name, sizeof(info->i_ld_name), name);
    if (securec_rv != EOK) {
        debug_log(DLOG_DEBUG, "%s: strcpy_s failed, ret = %d", __FUNCTION__, securec_rv);
    }
    return l_sml_adapter::sml_adapter_create_ld_as_cachecade(info);
}

void l_ld::register_to(lua_State *L, luawrap::stack_table &t)
{
    luawrap::restore_stack_top _s(L);

    // 导出 SML_LD_PROGRESS_INFO_S 结构给 lua 使用
    t.set("SML_LD_PROGRESS_INFO_S",  // SML_LD_PROGRESS_INFO_S
          luawrap::lua_class<SML_LD_PROGRESS_INFO_S>(L)
              .def_readonly("rebuild_state", &SML_LD_PROGRESS_INFO_S::rebuild_state)
              .def_readonly("rebuild_progress", &SML_LD_PROGRESS_INFO_S::rebuild_progress))
        .pop(L, 1);

    // 导出 SML_LD_BASIC_INFO_S 结构给 lua 使用
    auto cls = luawrap::lua_class<SML_LD_BASIC_INFO_S>(L).ctor<>();
    cls.def("reset_zero", c_func_wrap(L, reset_zero<SML_LD_BASIC_INFO_S>));
    cls.def("update", c_func_wrap(L, update_ld_info));
    def_properties(L, cls);
    t.set("SML_LD_BASIC_INFO_S", cls);

    // 导出 SML_LD_SET_PROPERTIES_S 结构给 lua 使用
    auto cls_set = luawrap::lua_class<SML_LD_SET_PROPERTIES_S>(L).ctor<>();
    cls_set.def("reset_zero", c_func_wrap(L, reset_zero<SML_LD_SET_PROPERTIES_S>));
    cls_set.def("set", c_func_wrap(L, set_ld_info));
    cls_set.def("start_ld_fgi", c_func_wrap(L, start_ld_fgi));
    cls_set.def("cancel_ld_fgi", c_func_wrap(L, cancel_ld_fgi));
    def_set_properties(L, cls_set);
    t.set("SML_LD_SET_PROPERTIES_S", cls_set);

    // 导出 SML_LD_TARGET_S 结构给 lua 使用
    auto cls_target = luawrap::lua_class<SML_LD_TARGET_S>(L).ctor<>();
    cls_target.def("reset_zero", c_func_wrap(L, reset_zero<SML_LD_TARGET_S>));
    cls_target.def("set_bootable", c_func_wrap(L, set_bootable));
    cls_target.def("delete_volume", c_func_wrap(L, delete_volume));
    def_target_properties(L, cls_target);
    t.set("SML_LD_TARGET_S", cls_target);

    // 导出 SML_RAID_ON_EXISTED_ARRAY_PARAM_S 结构给 lua 使用
    auto cls_add_ld = luawrap::lua_class<SML_RAID_ON_EXISTED_ARRAY_PARAM_S>(L).ctor<>();
    cls_add_ld.def("reset_zero", c_func_wrap(L, reset_zero<SML_RAID_ON_EXISTED_ARRAY_PARAM_S>));
    cls_add_ld.def("add_ld_on_exist_array", c_func_wrap(L, add_ld_on_exist_array));
    cls_add_ld.def("get_ld_id", c_func_wrap(L, exist_array_get_ld_id));
    t.set("SML_RAID_ON_EXISTED_ARRAY_PARAM_S", cls_add_ld);

    // 导出 SML_RAID_ON_NEW_ARRAY_PARAM_S 结构给 lua 使用
    auto cls_create_ld = luawrap::lua_class<SML_RAID_ON_NEW_ARRAY_PARAM_S>(L).ctor<>();
    cls_create_ld.def("reset_zero", c_func_wrap(L, reset_zero<SML_RAID_ON_NEW_ARRAY_PARAM_S>));
    cls_create_ld.def("create_ld_on_new_array", c_func_wrap(L, create_ld_on_new_array));
    cls_create_ld.def("get_ld_id", c_func_wrap(L, new_array_get_ld_id));
    t.set("SML_RAID_ON_NEW_ARRAY_PARAM_S", cls_create_ld);
}

void l_ld::register_cache_to(lua_State *L, luawrap::stack_table &t)
{
    luawrap::restore_stack_top _s(L);

    // 导出 SML_LD_SSCD_CACHING_ENABLE_S 结构给 lua 使用
    auto cls_ld_caching_enable = luawrap::lua_class<SML_LD_SSCD_CACHING_ENABLE_S>(L).ctor<>();
    cls_ld_caching_enable.def("reset_zero", c_func_wrap(L, reset_zero<SML_LD_SSCD_CACHING_ENABLE_S>));
    cls_ld_caching_enable.def("update", c_func_wrap(L, get_ld_sscd_caching_enable));
    def_caching_enable(L, cls_ld_caching_enable);
    t.set("SML_LD_SSCD_CACHING_ENABLE_S", cls_ld_caching_enable);

    // 导出 SML_SSCD_ASSOCIATED_LD_LIST_S 结构给 lua 使用
    auto cls_cache_ld_list = luawrap::lua_class<SML_SSCD_ASSOCIATED_LD_LIST_S>(L).ctor<>();
    cls_cache_ld_list.def("reset_zero", c_func_wrap(L, reset_zero<SML_SSCD_ASSOCIATED_LD_LIST_S>));
    cls_cache_ld_list.def("update", c_func_wrap(L, get_sscd_associated_ld_list));
    cls_cache_ld_list.def("get_list", c_func_wrap(L, sscd_associated_ld_list));
    def_cache_ld(L, cls_cache_ld_list);
    t.set("SML_SSCD_ASSOCIATED_LD_LIST_S", cls_cache_ld_list);

    // 导出 SML_LD_ASSOCIATED_SSCD_LIST_S 结构给 lua 使用
    auto cls_ld_cache_list = luawrap::lua_class<SML_LD_ASSOCIATED_SSCD_LIST_S>(L).ctor<>();
    cls_ld_cache_list.def("reset_zero", c_func_wrap(L, reset_zero<SML_LD_ASSOCIATED_SSCD_LIST_S>));
    cls_ld_cache_list.def("update", c_func_wrap(L, get_ld_associated_sscd_list));
    cls_ld_cache_list.def("get_list", c_func_wrap(L, ld_associated_sscd_list));
    def_ld_cache(L, cls_ld_cache_list);
    t.set("SML_LD_ASSOCIATED_SSCD_LIST_S", cls_ld_cache_list);

    // 导出 SML_LD_SET_CACHECADE_ASSOCIATION_S 结构给 lua 使用
    auto cls_ld_association = luawrap::lua_class<SML_LD_SET_CACHECADE_ASSOCIATION_S>(L).ctor<>();
    cls_ld_association.def("reset_zero", c_func_wrap(L, reset_zero<SML_LD_SET_CACHECADE_ASSOCIATION_S>));
    cls_ld_association.def("set_ld_cachecade", c_func_wrap(L, method_set_ld_cachecade));
    t.set("SML_LD_SET_CACHECADE_ASSOCIATION_S", cls_ld_association);

    // 导出 SML_RAID_CACHECADE_PARAM_S 结构给 lua 使用
    auto cls_ld_create_cache = luawrap::lua_class<SML_RAID_CACHECADE_PARAM_S>(L).ctor<>();
    cls_ld_create_cache.def("reset_zero", c_func_wrap(L, reset_zero<SML_RAID_CACHECADE_PARAM_S>));
    cls_ld_create_cache.def("create_ld_as_cachecade", c_func_wrap(L, create_ld_as_cachecade));
    t.set("SML_RAID_CACHECADE_PARAM_S", cls_ld_create_cache);
}

}  // namespace sml
