/* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
 * 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 "sml_errcodes.h"
#include "sml_public.h"
#include "pmc/pstorc.h"
#include "pmc/sysc_struct.h"
#include "pmc/sysc_cmd.h"
#include "sc_misc.h"
#include "sc_array.h"

/*
 * Description: 获取硬盘阵列ID列表
 */
LOCAL gint32 get_array_list(guint32 ctrl_id, SC_ARRAY_LIST *array_list)
{
    SC_LIB_CMD_PARAM_T lcp;

    (void)memset_s(&lcp, SC_LIB_CMD_PARAM_S, 0, SC_LIB_CMD_PARAM_S);

    lcp.cmdType = SC_CONFIG_CMD_TYPE;
    lcp.cmd = SC_GET_ARRAY_LIST;
    lcp.ctrlId = ctrl_id;
    lcp.dataSize = (guint32)sizeof(SC_ARRAY_LIST);
    lcp.pData = array_list;

    return ProcessSCCommandCall(&lcp);
}

/*
 * Description: 获取硬盘阵列ID列表
 */
gint32 pmc_get_ctrl_array_list(guint32 ctrl_id, gpointer data)
{
    if (data == NULL) {
        return SML_ERR_NULL_DATA;
    }

    SC_ARRAY_LIST array_list;

    (void)memset_s(&array_list, sizeof(array_list), 0, sizeof(array_list));

    gint32 ret = get_array_list(ctrl_id, &array_list);
    if (ret != SML_SUCCESS) {
        return ret;
    }

    SML_ARRAY_LIST_S *pArraylist = (SML_ARRAY_LIST_S *)data;

    pArraylist->array_count = array_list.count;
    for (guint16 i = 0; i < array_list.count; i++) {
        pArraylist->array_refs[i] = array_list.array_number[i];
    }

    return SML_SUCCESS;
}

/*
 * Description: 获取硬盘阵列信息
 */
LOCAL gint32 get_array_info(guint32 ctrl_id, guint16 array_ref, SC_ARRAY_INFO *array_info)
{
    SC_LIB_CMD_PARAM_T lcp;

    (void)memset_s(&lcp, SC_LIB_CMD_PARAM_S, 0, SC_LIB_CMD_PARAM_S);

    lcp.cmdType = SC_CONFIG_CMD_TYPE;
    lcp.cmd = SC_GET_ARRAY_INFO;
    lcp.ctrlId = ctrl_id;
    lcp.arrayRef.ref = array_ref;
    lcp.dataSize = (guint32)sizeof(SC_ARRAY_INFO);
    lcp.pData = array_info;

    return ProcessSCCommandCall(&lcp);
}

/*
 * Description: 获取硬盘阵列信息
 */
gint32 pmc_get_array_info(guint32 ctrl_id, guint16 array_ref, gpointer data)
{
    if (data == NULL) {
        return SML_ERR_NULL_DATA;
    }

    SC_ARRAY_INFO array_info;

    (void)memset_s(&array_info, sizeof(array_info), 0, sizeof(array_info));

    gint32 ret = get_array_info(ctrl_id, array_ref, &array_info);
    if (ret != SML_SUCCESS) {
        return ret;
    }

    SML_ARRAY_INFO_S *pArrayInfo = (SML_ARRAY_INFO_S *)data;
    pArrayInfo->ld_count = array_info.ld_count;
    guint16 i;
    for (i = 0; i < array_info.ld_count && i < SML_MAX_LOGICAL_DRIVES_PER_ARRAY; i++) {
        pArrayInfo->ld_ids[i] = array_info.ld_number[i];
    }

    pArrayInfo->pd_count = array_info.pd_count;
    for (i = 0; i < pArrayInfo->pd_count && i < SML_MAX_PHYSICAL_DRIVES_PER_ARRAY; i++) {
        pArrayInfo->pd_ids[i] = array_info.pd_number[i];
        pArrayInfo->pd_slots[i] = array_info.pd_slot[i];
        pArrayInfo->pd_enclosures[i] = array_info.pd_encl[i];
    }

    pArrayInfo->used_space = array_info.used_size / CAPACITY_CONVERSION_SIZE / CAPACITY_CONVERSION_SIZE;
    pArrayInfo->total_free_space = array_info.free_size / CAPACITY_CONVERSION_SIZE / CAPACITY_CONVERSION_SIZE;

    return SML_SUCCESS;
}
