-- 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.

local base_error = require 'messages.base'
local custom_error = require 'messages.custom'
local class = require 'mc.class'
local log = require 'mc.logging'

local RFERR_INSUFFICIENT_PRIVILEGE = 403
local MFI_STAT_WRONG_STATE = 0x32
local ERRCODE_METHOD_NOT_FOUND = -2005

local SM_CODE_E = {
    SM_CODE_INVALID_RAID_LEVEL = 0x2080,
    SM_CODE_INVALID_SPAN_DEPTH = 0x2081,
    SM_CODE_INVALID_PD_COUNT = 0x2082,
    SM_CODE_INVALID_PD_ID = 0x2085,
    SM_CODE_CAPACITY_OUT_OF_RANGE = 0x2086,
    SM_CODE_STRIP_SIZE_OUT_OF_RANGE = 0x2087,
    SM_CODE_READ_POLCIY_OUT_OF_RANGE = 0x2088,
    SM_CODE_WRITE_POLICY_OUT_OF_RANGE = 0x2089,
    SM_CODE_IO_POLICY_OUT_OF_RANGE = 0x208A,
    SM_CODE_ACCESS_POLICY_OUT_OF_RANGE = 0x208B,
    SM_CODE_DISK_CAHCE_POLICY_OUT_OF_RANGE = 0x208C,
    SM_CODE_INIT_TYPE_OUT_OF_RANGE = 0x208D,
    SM_CODE_LD_NAME_INVALID_ASCII = 0x208E,
    SM_CODE_LD_NAME_EXCEED_MAX_LEN = 0x208F,
    SM_CODE_UPGRADE_IN_PROGRESS = 0x2090,
    SM_CODE_NO_SPACE = 0x2091,
    SM_CODE_OPERATION_IN_PROGRESS = 0x2092,
    SM_CODE_GET_PD_LIST_FAILED = 0x20A0,
    SM_CODE_PD_NOT_IDENTIFIED = 0x20A1, -- 物理盘没有在控制器下
    SM_CODE_BUSY = 0x20C0,
    SM_CODE_PARA_DATA_ILLEGAL = 0x20CC,
    SM_CODE_NOT_SUPPORT_IN_PRESENT_STATE = 0x20D5   -- 控制器没初始化好
}

local SML_ERR_CODE_E = {
    SML_SUCCESS = 0,
    SML_ERR_I2C_READ_WRITE_FAILED = 0x1001,
    SML_ERR_MCTP_READ_WRITE_FAILED = 0x1002,
    SML_ERR_INVALID_PARAMETER = 0x1003,
    SML_ERR_REBOOT_REQUIRED = 0x1074,   -- 操作已完成 需要重启
    SML_ERR_OPERATION_NOT_POSSIBLE = 0x1076,
    SML_ERR_INVALID_POLICY = 0x1097,
    SML_ERR_CONFIG_PRESENT_ERROR = 0x1098,
    SML_ERR_INVALID_CMD = 0x10C1,
    SML_ERR_NULL_INFTERFACE = 0x10C2,
    SML_ERR_DATA_INVALID = 0x10C8,

    SML_ERR_CTRL_INDEX_INVALID = 0x1101,    -- 控制器ID无效
    SML_ERR_CTRL_NOT_REGISTERED = 0x1103,   -- 控制器未注册
    SML_ERR_CTRL_INIT_NOT_COMPLETED = 0x1104,   -- 控制器初始化未完成
    SML_ERR_CTRL_SET_PROP_UPLEVEL_FUNC_DISABLED = 0x1110,
    SML_ERR_CTRL_STATUS_INVALID = 0x11D5,   -- 控制器状态无效
    SML_ERR_CTRL_OPERATION_NOT_SUPPORT = 0x11D7,    -- 控制器不支持操作
    SML_ERR_CTRL_BBU_STATUS_ABNORMAL = 0x11DA,  -- 控制器状态异常
    SML_ERR_CTRL_NO_EDITABLE_LD = 0x11DB,
    SML_ERR_CTRL_RCP_NOT_IN_RANGE = 0x11DC,

    SML_ERR_LD_INVALID_TARGET_ID = 0x1201,
    SML_ERR_LD_DELETE_ON_SNAPSHOTS_ENABLED = 0x1210,
    SML_ERR_LD_INIT_IN_PROGRESS = 0x1218,
    SML_ERR_LD_PROPERTY_SET_NOT_ALLOWED = 0x1220,
    SML_ERR_LD_PROPERTY_SET_ONLY_DEFAULT_ALLOWED = 0x1221,
    SML_ERR_LD_NO_SSCD_OR_INVALID_NUM_OF_SSCD = 0x1222,
    SML_ERR_LD_SET_CACHING_ENABLE_FOR_LD_WITH_SSD = 0x1223,
    SML_ERR_LD_SIZE_SHRINK_NOT_ALLOWED = 0x1224,
    SML_ERR_LD_STATE_UNSUPPORTED_TO_SET = 0x1225,
    SML_ERR_LD_INVALID_POLICY = 0x1297,
    SML_ERR_LD_OPERATION_NOT_SUPPORT = 0x12D5,

    SML_ERR_PD_INVALID_DEVICE_ID = 0x1301,  -- 物理盘ID无效
    SML_ERR_PD_MAKESPARE_NOT_ALLOWED = 0x1310,  -- 物理盘不允许设置热备
    SML_ERR_PD_SPARE_SDD_HDD_MIXED = 0x1312,
    SML_ERR_PD_SPARE_FOR_RAID0_LD = 0x1314, -- 试图将物理盘设置为RAID0逻辑盘的热备盘
    SML_ERR_PD_SPARE_SDD_SAS_SATA_MIXED = 0x1311,
    SML_ERR_PD_STATE_UNSUPPORTED_TO_SET = 0x131f,
    SML_ERR_PD_CLEAR_IN_PROGRESS = 0x1325,
    SML_ERR_PD_MAX_UNCONFIGURED = 0x135f,
    SML_ERR_PD_SCSI_STATUS_BUSY = 0x13C0,
    SML_ERR_PD_SCSI_DEVICE_FAULT = 0x13C4,
    SML_ERR_PD_SCSI_STATUS_FAIL = 0x13C5,
    SML_ERR_PD_OPERATION_NOT_SUPPORT = 0x13D5,    -- 物理盘不支持
    SML_ERR_PD_IS_SMART_TEST = 0x13F0,

    SML_ERR_CONFIG_RESOURCE_CONFLICT = 0x140B,
    SML_ERR_CONFIG_INVALID_PARAM_SPAN_DEPTH = 0x1410,          -- 创建逻辑盘的span depth参数无效
    SML_ERR_CONFIG_INVALID_PARAM_NUM_DRIVE_PER_SPAN = 0x1411,  -- 创建逻辑盘的num drive per span参数无效
    SML_ERR_CONFIG_INVALID_PARAM_REPEATED_PD_ID = 0x1412,      -- 创建逻辑盘的物理盘列表中有重复ID
    SML_ERR_CONFIG_INVALID_PARAM_RAID_LEVEL = 0x1413,          -- 创建逻辑盘的RAID级别参数无效
    SML_ERR_CONFIG_INVALID_PARAM_ARRAY_REF = 0x1414,           -- 创建逻辑盘的Array ID参数无效
    SML_ERR_CONFIG_INVALID_PARAM_CAPACITY_TOO_SMALL = 0x1415,  -- 创建逻辑盘指定的容量空间太小
    SML_ERR_CONFIG_INVALID_PARAM_CAPACITY_TOO_LARGE = 0x1416,  -- 创建逻辑盘指定的容量空间太大
    SML_ERR_CONFIG_ARRAY_NUM_REACHED_LIMIT = 0x1430,           -- Array个数已经到达最大值
    SML_ERR_CONFIG_ARRAY_SIZE_TOO_SMALL = 0x1431,              -- 指定用于创建逻辑盘的Array上空间太小
    SML_ERR_CONFIG_ARRAY_NO_AVAILABLE_SPACE = 0x1432,          -- 指定用于创建逻辑盘的Array上没有可用空间
    SML_ERR_CONFIG_INVALID_PD_BOOT_SECTOR_FOUND = 0x1441,
    SML_ERR_CONFIG_INVALID_PD_NON_SUPPORTED = 0x1442,          -- 用于创建逻辑盘的物理盘ID指向的是不支持的物理设备
    SML_ERR_CONFIG_INVALID_PD_SCSI_DEV_TYPE = 0x1443,
    SML_ERR_CONFIG_INVALID_PD_IN_USE = 0x1444,                 -- 用于创建逻辑盘的物理盘已经被使用
    SML_ERR_CONFIG_INVALID_PD_SDD_HDD_MIXED = 0x1445,          --用于创建逻辑盘的物理盘中同时有SSD和HDD，而控制器不支持混接在一个逻辑盘
    SML_ERR_CONFIG_INVALID_PD_SDD_SAS_SATA_MIXED = 0x1446,     -- 用于创建逻辑盘的SSD物理盘中同时有SAS和SATA接口，而控制器不支持混接在一个逻辑盘
    SML_ERR_CONFIG_INVALID_PD_WITH_FOREIGN_CONFIG = 0x1447,
    SML_ERR_CONFIG_INVALID_PD_NON_SDD_FOR_CACHECADE = 0x1448,  -- 用于创建CacheCade逻辑盘的物理盘不是SSD硬盘
    SML_ERR_CONFIG_INVALID_PD_OTHER_ERROR = 0x144F,            -- 用于创建逻辑盘的物理盘有其他不适于创建的错误
    SML_ERR_CONFIG_TARGET_LD_ID_EXHAUSTED = 0x1450,
    SML_ERR_CONFIG_BLOCK_SIZE_NOT_SAME = 0x1451,
    SML_ERR_CONFIG_OPERATION_NOT_SUPPORT = 0x14D5,
    SML_ERR_CONFIG_NO_FOREIGN_CONFIG = 0x14D6,
    SML_ERR_CONFIG_INCOMPLETE_FOREIGN_CONFIG = 0x14D7,
    SML_ERR_CONFIG_ASSOCIATED_LD_SIZE_OUT_OF_RANGE = 0x14D8
}

-- 获取对应错误码需要的报错信息
local function get_controller_error_message(error_code)
    local switch_error_param = {
        [SML_ERR_CODE_E.SML_ERR_CTRL_STATUS_INVALID] = 'CurrentStatusNotSupportOperation',
        [SML_ERR_CODE_E.SML_ERR_CTRL_INIT_NOT_COMPLETED] = 'CurrentStatusNotSupportOperation',
        [SML_ERR_CODE_E.SML_ERR_CTRL_INDEX_INVALID] = 'CurrentStatusNotSupportOperation',
        [SML_ERR_CODE_E.SML_ERR_I2C_READ_WRITE_FAILED] = 'CurrentStatusNotSupportOperation',
        [SML_ERR_CODE_E.SML_ERR_MCTP_READ_WRITE_FAILED] = 'CurrentStatusNotSupportOperation',
        [SML_ERR_CODE_E.SML_ERR_CTRL_NOT_REGISTERED] = 'CurrentStatusNotSupportOperation',
        [SM_CODE_E.SM_CODE_NOT_SUPPORT_IN_PRESENT_STATE] = 'CurrentStatusNotSupportOperation',
        [SML_ERR_CODE_E.SML_ERR_CTRL_SET_PROP_UPLEVEL_FUNC_DISABLED] = 'CurrentStatusNotSupportOperation',
        [SM_CODE_E.SM_CODE_GET_PD_LIST_FAILED] = 'CurrentStatusNotSupportOperation',
        [SML_ERR_CODE_E.SML_ERR_CTRL_NO_EDITABLE_LD] = 'CurrentStatusNotSupportOperation',
        [SML_ERR_CODE_E.SML_ERR_CTRL_OPERATION_NOT_SUPPORT] = 'RAIDControllerNotSupported',
        [SML_ERR_CODE_E.SML_ERR_INVALID_PARAMETER] = 'RAIDControllerNotSupported',
        [SML_ERR_CODE_E.SML_ERR_OPERATION_NOT_POSSIBLE] = 'RAIDControllerNotSupported',
        [SM_CODE_E.SM_CODE_PD_NOT_IDENTIFIED] = 'InvalidValue',
        [SML_ERR_CODE_E.SML_ERR_DATA_INVALID] = 'InvalidValue',
        [SML_ERR_CODE_E.SML_ERR_CONFIG_PRESENT_ERROR] = 'ConfigurationExist',
        [SM_CODE_E.SM_CODE_PARA_DATA_ILLEGAL] = 'PropertyValueNotInList',
        [SML_ERR_CODE_E.SML_ERR_NULL_INFTERFACE] = 'ActionParameterNotSupported',
        [SML_ERR_CODE_E.SML_ERR_CTRL_BBU_STATUS_ABNORMAL] = 'PropertyModificationNotSupportedByBBUStatus',
        [SM_CODE_E.SM_CODE_OPERATION_IN_PROGRESS] = 'OperationInProcess',
        [SML_ERR_CODE_E.SML_ERR_REBOOT_REQUIRED] = 'RAIDControllerSetSuccessfully',
        [SM_CODE_E.SM_CODE_INVALID_SPAN_DEPTH] = 'NumberOfSpansInvalid',
        [SM_CODE_E.SM_CODE_INVALID_PD_ID] = 'PhysicalDiskIdInvalid',
        [SM_CODE_E.SM_CODE_INVALID_PD_COUNT] = 'PhysicalDiskIdCountError',
        [SM_CODE_E.SM_CODE_INVALID_RAID_LEVEL] = 'RaidControllerLevelInvalid',
        [SM_CODE_E.SM_CODE_CAPACITY_OUT_OF_RANGE] = 'VolumeCapacityOutRange',
        [SM_CODE_E.SM_CODE_STRIP_SIZE_OUT_OF_RANGE] = 'StripeSizeError',
        [SM_CODE_E.SM_CODE_READ_POLCIY_OUT_OF_RANGE] = 'InvalidValue',
        [SM_CODE_E.SM_CODE_WRITE_POLICY_OUT_OF_RANGE] = 'InvalidValue',
        [SM_CODE_E.SM_CODE_IO_POLICY_OUT_OF_RANGE] = 'InvalidValue',
        [SM_CODE_E.SM_CODE_ACCESS_POLICY_OUT_OF_RANGE] = 'InvalidValue',
        [SM_CODE_E.SM_CODE_DISK_CAHCE_POLICY_OUT_OF_RANGE] = 'InvalidValue',
        [SM_CODE_E.SM_CODE_INIT_TYPE_OUT_OF_RANGE] = 'InvalidValue',
        [SM_CODE_E.SM_CODE_LD_NAME_EXCEED_MAX_LEN] = 'PropertyValueFormatError',
        [SML_ERR_CODE_E.SML_ERR_LD_INVALID_TARGET_ID] = 'OperationFailed',
        [SML_ERR_CODE_E.SML_ERR_CONFIG_BLOCK_SIZE_NOT_SAME] = 'DifferentDriveSectorsSize',
        [SML_ERR_CODE_E.SML_ERR_PD_CLEAR_IN_PROGRESS] = 'DriveStatusNotSupported'
    }
    return switch_error_param[error_code]
end

local ctrl_error_map = {
    -- 控制器操作时可能的错误处理
    [RFERR_INSUFFICIENT_PRIVILEGE] = custom_error.PropertyModificationNeedPrivilege,
    [SML_ERR_CODE_E.SML_ERR_CTRL_STATUS_INVALID] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_CTRL_INIT_NOT_COMPLETED] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_CTRL_INDEX_INVALID] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_I2C_READ_WRITE_FAILED] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_MCTP_READ_WRITE_FAILED] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_CTRL_NOT_REGISTERED] = custom_error.CurrentStatusNotSupportOperation,
    [SM_CODE_E.SM_CODE_NOT_SUPPORT_IN_PRESENT_STATE] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_CTRL_SET_PROP_UPLEVEL_FUNC_DISABLED] = custom_error.CurrentStatusNotSupportOperation,
    [SM_CODE_E.SM_CODE_GET_PD_LIST_FAILED] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_CTRL_NO_EDITABLE_LD] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_CTRL_OPERATION_NOT_SUPPORT] = custom_error.RAIDControllerNotSupported,
    [SML_ERR_CODE_E.SML_ERR_INVALID_PARAMETER] = custom_error.RAIDControllerNotSupported,
    [SML_ERR_CODE_E.SML_ERR_OPERATION_NOT_POSSIBLE] = custom_error.RAIDControllerNotSupported,
    [SM_CODE_E.SM_CODE_PD_NOT_IDENTIFIED] = custom_error.InvalidValue,
    [SML_ERR_CODE_E.SML_ERR_DATA_INVALID] = custom_error.InvalidValue,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_PRESENT_ERROR] = custom_error.ConfigurationExist,
    [SM_CODE_E.SM_CODE_PARA_DATA_ILLEGAL] = base_error.PropertyValueNotInList,
    [SML_ERR_CODE_E.SML_ERR_NULL_INFTERFACE] = base_error.ActionParameterNotSupported,
    [SML_ERR_CODE_E.SML_ERR_CTRL_BBU_STATUS_ABNORMAL] = custom_error.PropertyModificationNotSupportedByBBUStatus,
    [SM_CODE_E.SM_CODE_OPERATION_IN_PROGRESS] = custom_error.OperationInProcess,
    [SML_ERR_CODE_E.SML_ERR_REBOOT_REQUIRED] = custom_error.RAIDControllerSetSuccessfully,
    [SM_CODE_E.SM_CODE_INVALID_SPAN_DEPTH] = custom_error.NumberOfSpansInvalid,
    [SM_CODE_E.SM_CODE_INVALID_PD_ID] = custom_error.PhysicalDiskIdInvalid,
    [SM_CODE_E.SM_CODE_INVALID_PD_COUNT] = custom_error.PhysicalDiskIdCountError,
    [SM_CODE_E.SM_CODE_INVALID_RAID_LEVEL] = custom_error.RaidControllerLevelInvalid,
    [SM_CODE_E.SM_CODE_CAPACITY_OUT_OF_RANGE] = custom_error.VolumeCapacityOutRange,
    [SM_CODE_E.SM_CODE_STRIP_SIZE_OUT_OF_RANGE] = custom_error.StripeSizeError,
    [SM_CODE_E.SM_CODE_READ_POLCIY_OUT_OF_RANGE] = custom_error.InvalidValue,
    [SM_CODE_E.SM_CODE_WRITE_POLICY_OUT_OF_RANGE] = custom_error.InvalidValue,
    [SM_CODE_E.SM_CODE_IO_POLICY_OUT_OF_RANGE] = custom_error.InvalidValue,
    [SM_CODE_E.SM_CODE_ACCESS_POLICY_OUT_OF_RANGE] = custom_error.InvalidValue,
    [SM_CODE_E.SM_CODE_DISK_CAHCE_POLICY_OUT_OF_RANGE] = custom_error.InvalidValue,
    [SM_CODE_E.SM_CODE_INIT_TYPE_OUT_OF_RANGE] = custom_error.InvalidValue,
    [SM_CODE_E.SM_CODE_LD_NAME_EXCEED_MAX_LEN] = base_error.PropertyValueFormatError,
    [SML_ERR_CODE_E.SML_ERR_LD_INVALID_TARGET_ID] = custom_error.OperationFailed,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_BLOCK_SIZE_NOT_SAME] = custom_error.DifferentDriveSectorsSize,
    [SML_ERR_CODE_E.SML_ERR_PD_CLEAR_IN_PROGRESS] = custom_error.DriveStatusNotSupported,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_NO_FOREIGN_CONFIG] = custom_error.NoForeignConfig,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_INCOMPLETE_FOREIGN_CONFIG] = custom_error.IncompleteForeignConfig
}

local volume_error_map = {
    -- 逻辑盘操作时可能的错误处理
    [SML_ERR_CODE_E.SML_ERR_CTRL_INDEX_INVALID] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_LD_INVALID_TARGET_ID] = custom_error.OperationFailed,
    [SM_CODE_E.SM_CODE_NOT_SUPPORT_IN_PRESENT_STATE] = custom_error.ModifyfailedWithRAIDCardState,
    [SML_ERR_CODE_E.SML_ERR_CTRL_STATUS_INVALID] = custom_error.ModifyfailedWithRAIDCardState,
    [SML_ERR_CODE_E.SML_ERR_INVALID_PARAMETER] = custom_error.ModifyfailedWithCachecade,
    [SML_ERR_CODE_E.SML_ERR_LD_PROPERTY_SET_NOT_ALLOWED] = custom_error.ModifyfailedWithCachecade,
    [SML_ERR_CODE_E.SML_ERR_LD_OPERATION_NOT_SUPPORT] = custom_error.ModifyfailedWithRaidControllerNotSupport,
    [SM_CODE_E.SM_CODE_PARA_DATA_ILLEGAL] = base_error.PropertyValueNotInList,
    [SML_ERR_CODE_E.SML_ERR_LD_NO_SSCD_OR_INVALID_NUM_OF_SSCD] = custom_error.NoCachecadeVolume,
    [SML_ERR_CODE_E.SML_ERR_LD_PROPERTY_SET_ONLY_DEFAULT_ALLOWED] = custom_error.ModifyfailedWithSSD,
    [SML_ERR_CODE_E.SML_ERR_LD_SET_CACHING_ENABLE_FOR_LD_WITH_SSD] = custom_error.ModifyfailedWithSSD,
    [SM_CODE_E.SM_CODE_LD_NAME_INVALID_ASCII] = custom_error.InvalidVolumeName,
    [SML_ERR_CODE_E.SML_ERR_INVALID_POLICY] = custom_error.InvalidValue,
    [SM_CODE_E.SM_CODE_LD_NAME_EXCEED_MAX_LEN] = custom_error.PropertyValueExceedsMaxLength,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_INVALID_PD_NON_SDD_FOR_CACHECADE] = custom_error.NonSSDExist,
    [SML_ERR_CODE_E.SML_ERR_CTRL_BBU_STATUS_ABNORMAL] = custom_error.PropertyModificationNotSupportedByBBUStatus,
    [SML_ERR_CODE_E.SML_ERR_LD_SIZE_SHRINK_NOT_ALLOWED] = custom_error.VolumeShrinkNotAllowed,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_INVALID_PARAM_CAPACITY_TOO_LARGE] = custom_error.VolumeCapacityOutRange,
    [SML_ERR_CODE_E.SML_ERR_LD_INVALID_POLICY] = custom_error.InvalidValue,
    [SML_ERR_CODE_E.SML_ERR_OPERATION_NOT_POSSIBLE] = custom_error.PropertyModificationNotSupported,
    [SML_ERR_CODE_E.SML_ERR_LD_STATE_UNSUPPORTED_TO_SET] = custom_error.OperationFailed,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_OPERATION_NOT_SUPPORT] = custom_error.OperationFailed,
    [SM_CODE_E.SM_CODE_OPERATION_IN_PROGRESS] = custom_error.OperationInProcess,
    [SML_ERR_CODE_E.SML_ERR_REBOOT_REQUIRED] = custom_error.VolumeSetSuccessfully
}

local drive_error_map = {
    -- 硬盘操作时可能的错误处理
    [SML_ERR_CODE_E.SML_ERR_CTRL_OPERATION_NOT_SUPPORT] = custom_error.RAIDControllerNotSupported,
    [SM_CODE_E.SM_CODE_PARA_DATA_ILLEGAL] = base_error.PropertyValueNotInList,
    [SM_CODE_E.SM_CODE_PD_NOT_IDENTIFIED] = custom_error.PropertyNotSupportedModificationByCurrentStatus,
    [SM_CODE_E.SM_CODE_NOT_SUPPORT_IN_PRESENT_STATE] = custom_error.PropertyNotSupportedModificationByCurrentStatus,
    [SML_ERR_CODE_E.SML_ERR_PD_INVALID_DEVICE_ID] = custom_error.PropertyNotSupportedModificationByCurrentStatus,
    [ERRCODE_METHOD_NOT_FOUND] = custom_error.PropertyNotSupportedModificationByCurrentStatus,
    [SM_CODE_E.SM_CODE_BUSY] = custom_error.PropertyNotSupportedModificationByCurrentStatus,
    [SM_CODE_E.SM_CODE_GET_PD_LIST_FAILED] = custom_error.PropertyNotSupportedModificationByCurrentStatus,
    [SML_ERR_CODE_E.SML_ERR_PD_MAX_UNCONFIGURED] = custom_error.PropertyNotSupportedModificationByCurrentStatus,
    [SML_ERR_CODE_E.SML_ERR_I2C_READ_WRITE_FAILED] = custom_error.PropertyNotSupportedModificationByCurrentStatus,
    [SML_ERR_CODE_E.SML_ERR_PD_MAKESPARE_NOT_ALLOWED] = custom_error.PropertyModificationNotSupportedByPDStatus,
    [MFI_STAT_WRONG_STATE] = custom_error.PropertyModificationNotSupportedByPDStatus,
    [SML_ERR_CODE_E.SML_ERR_INVALID_PARAMETER] = custom_error.PropertyModificationNotSupportedByPDStatus,
    [SML_ERR_CODE_E.SML_ERR_INVALID_CMD] = custom_error.PropertyModificationNotSupportedByPDStatus,
    [SML_ERR_CODE_E.SML_ERR_PD_STATE_UNSUPPORTED_TO_SET] = custom_error.PropertyModificationNotSupportedByPDStatus,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_RESOURCE_CONFLICT] = custom_error.PropertyModificationNotSupportedByPDStatus,
    [SML_ERR_CODE_E.SML_ERR_PD_SPARE_FOR_RAID0_LD] = custom_error.PropertyModificationFailedByRAIDlevelNotSupported,
    [SML_ERR_CODE_E.SML_ERR_PD_SPARE_SDD_SAS_SATA_MIXED] = custom_error.PropertyModificationFailedByIterfaceConflict,
    [SML_ERR_CODE_E.SML_ERR_PD_SPARE_SDD_HDD_MIXED] = custom_error.PropertyModificationFailedByMediaTypeConflict,
    [SML_ERR_CODE_E.SML_ERR_CTRL_INIT_NOT_COMPLETED] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_CTRL_NOT_REGISTERED] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_CTRL_INDEX_INVALID] = custom_error.CurrentStatusNotSupportOperation,
    [SML_ERR_CODE_E.SML_ERR_CTRL_STATUS_INVALID] = custom_error.OperationFailed,
    [SML_ERR_CODE_E.SML_ERR_PD_OPERATION_NOT_SUPPORT] = custom_error.RAIDControllerNotSupported,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_ASSOCIATED_LD_SIZE_OUT_OF_RANGE] = custom_error.AssociatedVolumeCapacityOutRange,
    [SML_ERR_CODE_E.SML_ERR_CONFIG_BLOCK_SIZE_NOT_SAME] = custom_error.DifferentDriveSectorsSize,
    [SM_CODE_E.SM_CODE_OPERATION_IN_PROGRESS] = custom_error.OperationInProcess
}

-- 所有的错误映射集合
local error_maps = {
    ['Controller'] = ctrl_error_map,
    ['Drive'] = drive_error_map,
    ['Volume'] = volume_error_map,
}

local error_engine = class()

error_engine.SM_CODE_E = SM_CODE_E
error_engine.SML_ERR_CODE_E = SML_ERR_CODE_E

-- 获取对应错误码需要的报错信息
local function get_controller_error_param(error_code, prop_name, prop_val, extra)
    local switch_error_param = {
        [SML_ERR_CODE_E.SML_ERR_CTRL_STATUS_INVALID] = {},
        [SML_ERR_CODE_E.SML_ERR_CTRL_INIT_NOT_COMPLETED] = {},
        [SML_ERR_CODE_E.SML_ERR_CTRL_INDEX_INVALID] = {},
        [SML_ERR_CODE_E.SML_ERR_I2C_READ_WRITE_FAILED] = {},
        [SML_ERR_CODE_E.SML_ERR_MCTP_READ_WRITE_FAILED] = {},
        [SML_ERR_CODE_E.SML_ERR_CTRL_NOT_REGISTERED] = {},
        [SM_CODE_E.SM_CODE_NOT_SUPPORT_IN_PRESENT_STATE] = {},
        [SML_ERR_CODE_E.SML_ERR_CTRL_SET_PROP_UPLEVEL_FUNC_DISABLED] = {},
        [SM_CODE_E.SM_CODE_GET_PD_LIST_FAILED] = {},
        [SML_ERR_CODE_E.SML_ERR_CTRL_NO_EDITABLE_LD] = {},
        [SML_ERR_CODE_E.SML_ERR_CTRL_OPERATION_NOT_SUPPORT] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_INVALID_PARAMETER] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_OPERATION_NOT_POSSIBLE] = {prop_name},
        [SM_CODE_E.SM_CODE_PD_NOT_IDENTIFIED] = {prop_val, prop_name},
        [SML_ERR_CODE_E.SML_ERR_DATA_INVALID] = {prop_val, prop_name},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_PRESENT_ERROR] = {},
        [SM_CODE_E.SM_CODE_PARA_DATA_ILLEGAL] = {prop_val, prop_name},
        [SML_ERR_CODE_E.SML_ERR_NULL_INFTERFACE] = {prop_val, prop_name},
        [SML_ERR_CODE_E.SML_ERR_CTRL_BBU_STATUS_ABNORMAL] = {},
        [SM_CODE_E.SM_CODE_OPERATION_IN_PROGRESS] = {},
        [SML_ERR_CODE_E.SML_ERR_REBOOT_REQUIRED] = {},
        [SM_CODE_E.SM_CODE_INVALID_SPAN_DEPTH] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_INVALID_PD_ID] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_INVALID_PD_COUNT] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_INVALID_RAID_LEVEL] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_CAPACITY_OUT_OF_RANGE] = {prop_val},
        [SM_CODE_E.SM_CODE_STRIP_SIZE_OUT_OF_RANGE] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_READ_POLCIY_OUT_OF_RANGE] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_WRITE_POLICY_OUT_OF_RANGE] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_IO_POLICY_OUT_OF_RANGE] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_ACCESS_POLICY_OUT_OF_RANGE] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_DISK_CAHCE_POLICY_OUT_OF_RANGE] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_INIT_TYPE_OUT_OF_RANGE] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_LD_NAME_EXCEED_MAX_LEN] = {prop_val, prop_name},
        [SML_ERR_CODE_E.SML_ERR_LD_INVALID_TARGET_ID] = {},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_BLOCK_SIZE_NOT_SAME] = {},
        [SML_ERR_CODE_E.SML_ERR_PD_CLEAR_IN_PROGRESS] = {prop_val, prop_name},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_NO_FOREIGN_CONFIG] = {},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_INCOMPLETE_FOREIGN_CONFIG] = {}
    }
    return switch_error_param[error_code]
end

-- 获取对应错误码需要的报错信息
local function get_drive_error_param(error_code, prop_name, prop_val, extra)
    local switch_error_param = {
        [ERRCODE_METHOD_NOT_FOUND] = {prop_name},
        [SM_CODE_E.SM_CODE_BUSY] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_CTRL_OPERATION_NOT_SUPPORT] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_PD_INVALID_DEVICE_ID] = {prop_name},
        [SM_CODE_E.SM_CODE_PARA_DATA_ILLEGAL] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_PD_NOT_IDENTIFIED] = {prop_name},
        [SM_CODE_E.SM_CODE_NOT_SUPPORT_IN_PRESENT_STATE] = {prop_name},
        [SM_CODE_E.SM_CODE_GET_PD_LIST_FAILED] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_PD_MAX_UNCONFIGURED] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_I2C_READ_WRITE_FAILED] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_PD_MAKESPARE_NOT_ALLOWED] = {prop_name},
        [MFI_STAT_WRONG_STATE] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_INVALID_PARAMETER] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_INVALID_CMD] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_PD_STATE_UNSUPPORTED_TO_SET] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_RESOURCE_CONFLICT] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_PD_SPARE_FOR_RAID0_LD] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_PD_SPARE_SDD_SAS_SATA_MIXED] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_PD_SPARE_SDD_HDD_MIXED] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_CTRL_INDEX_INVALID] = {},
        [SML_ERR_CODE_E.SML_ERR_CTRL_INIT_NOT_COMPLETED] = {},
        [SML_ERR_CODE_E.SML_ERR_CTRL_NOT_REGISTERED] = {},
        [SML_ERR_CODE_E.SML_ERR_CTRL_STATUS_INVALID] = {},
        [SML_ERR_CODE_E.SML_ERR_PD_OPERATION_NOT_SUPPORT] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_ASSOCIATED_LD_SIZE_OUT_OF_RANGE] = {},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_BLOCK_SIZE_NOT_SAME] = {},
        [SM_CODE_E.SM_CODE_OPERATION_IN_PROGRESS] = {}
    }
    return switch_error_param[error_code]
end

-- 获取对应错误码需要的报错信息
local function get_volume_error_param(error_code, prop_name, prop_val, extra)
    local switch_error_param = {
        [SML_ERR_CODE_E.SML_ERR_CTRL_INDEX_INVALID] = {},
        [SM_CODE_E.SM_CODE_NOT_SUPPORT_IN_PRESENT_STATE] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_CTRL_STATUS_INVALID] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_INVALID_PARAMETER] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_LD_PROPERTY_SET_NOT_ALLOWED] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_LD_OPERATION_NOT_SUPPORT] = {prop_name},
        [SM_CODE_E.SM_CODE_PARA_DATA_ILLEGAL] = {prop_val, prop_name},
        [SML_ERR_CODE_E.SML_ERR_LD_NO_SSCD_OR_INVALID_NUM_OF_SSCD] = {},
        [SML_ERR_CODE_E.SML_ERR_LD_PROPERTY_SET_ONLY_DEFAULT_ALLOWED] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_LD_SET_CACHING_ENABLE_FOR_LD_WITH_SSD] = {prop_name},
        [SM_CODE_E.SM_CODE_LD_NAME_INVALID_ASCII] = {},
        [SML_ERR_CODE_E.SML_ERR_INVALID_POLICY] = {prop_val, prop_name},
        [SM_CODE_E.SM_CODE_LD_NAME_EXCEED_MAX_LEN] = {prop_val, prop_name, extra},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_INVALID_PD_NON_SDD_FOR_CACHECADE] = {prop_val, prop_name},
        [SML_ERR_CODE_E.SML_ERR_CTRL_BBU_STATUS_ABNORMAL] = {},
        [SML_ERR_CODE_E.SML_ERR_LD_SIZE_SHRINK_NOT_ALLOWED] = {},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_INVALID_PARAM_CAPACITY_TOO_LARGE] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_LD_INVALID_POLICY] = {prop_val, prop_name},
        [SML_ERR_CODE_E.SML_ERR_OPERATION_NOT_POSSIBLE] = {prop_name},
        [SML_ERR_CODE_E.SML_ERR_LD_INVALID_TARGET_ID] = {},
        [SML_ERR_CODE_E.SML_ERR_LD_STATE_UNSUPPORTED_TO_SET] = {},
        [SML_ERR_CODE_E.SML_ERR_CONFIG_OPERATION_NOT_SUPPORT] = {},
        [SM_CODE_E.SM_CODE_OPERATION_IN_PROGRESS] = {},
        [SML_ERR_CODE_E.SML_ERR_REBOOT_REQUIRED] = {}
    }
    return switch_error_param[error_code]
end

local function raise_error(obj_type, error_code, param_arg)
    local error_map = error_maps[obj_type]
    local error_func = error_map[error_code]
    if not error_func then
        log:error('Operation failed and return %s', error_code)
        return base_error.InternalError()
    end
    local switch_error_func = {
        [0] = function(args)
            return error_func()
        end,
        [1] = function(args)
            return error_func(args[1])
        end,
        [2] = function(args)
            return error_func(args[1], args[2])
        end,
        [3] = function(args)
            return error_func(args[1], args[2], args[3])
        end
    }
    local input_num = #param_arg
    return switch_error_func[input_num](param_arg)
end

-- 控制器的错误引擎
function error_engine.raise_controller_error(ctx, error_code, prop_name, prop_val, extra)
    local param_arg = get_controller_error_param(error_code, prop_name, prop_val, extra)
    if ctx and ctx.netfn then
        error({err_code = error_code})
    end
    error(raise_error("Controller", error_code, param_arg))
end

-- 控制器的错误引擎
function error_engine.get_controller_error_message(error_code, prop_name, prop_val, extra)
    local error_messageid = get_controller_error_message(error_code)
    local param_arg = get_controller_error_param(error_code, prop_name, prop_val, extra)
    return error_messageid, param_arg
end

-- 硬盘的错误引擎
function error_engine.raise_drive_error(ctx, error_code, prop_name, prop_val, extra)
    local param_arg = get_drive_error_param(error_code, prop_name, prop_val, extra)
    if ctx and ctx.netfn then
        error({err_code = error_code})
    end
    error(raise_error("Drive", error_code, param_arg))
end

-- 逻辑盘的错误引擎
function error_engine.raise_volume_error(ctx, error_code, prop_name, prop_val, extra)
    local param_arg = get_volume_error_param(error_code, prop_name, prop_val, extra)
    if ctx and ctx.netfn then
        error({err_code = error_code})
    end
    error(raise_error("Volume", error_code, param_arg))
end

return error_engine