{%
    local VENDER_LSI = 0
    local VENDER_PMC = 1
    local VENDER_HUAWEI = 2
    local PMC_3152_8I_SMART_RAID = 64
    local PMC_2100_8I_SMART_HBA = 65
    local HI1880_SP186_M_16i = 96
    local HI1880_SP186_M_8i = 113
    local sms_state = 0
    local str_char_033 = string.char(0x1b)
    local function dal_test_controller_vendor(type_id, vendor_id)
        if vendor_id == VENDER_LSI then
            if type_id < PMC_3152_8I_SMART_RAID then
                return true
            end 
        elseif vendor_id == VENDER_PMC then
            if type_id == PMC_3152_8I_SMART_RAID or type_id == PMC_2100_8I_SMART_HBA  then
                return true
            end
        elseif vendor_id == VENDER_HUAWEI then
            if type_id >= HI1880_SP186_M_16i and type_id <= HI1880_SP186_M_8i then
                return true
            end
        end
        return false
    end
    local function get_controller_oob_support(oob_support)
        if oob_support == 1 then
            return 'Yes'
        else
            return 'No'
        end
    end
    -- 将Raid级别信息拼装成字符串
    local function get_supported_raid_level(supported_raid_types)
        if #supported_raid_types == 0 then
            return 'N/A'
        end
        local supported_raid_level = ''
        for i = 1, #supported_raid_types do
            local find_l, find_r = string.find(supported_raid_types[i], 'RAID', 1, true)
            if find_r then
                local raid_level_num = string.sub(supported_raid_types[i], find_r + 1)
                if i > 1 then
                    supported_raid_level = supported_raid_level .. '/' .. raid_level_num
                else
                    supported_raid_level = supported_raid_level .. raid_level_num
                end
            end
        end
        return 'RAID(' .. supported_raid_level .. ')'
    end
    local function get_controller_work_mode(work_mode)
        if work_mode == 'RAID' then
            return 'RAID'
        elseif work_mode == 'HBA' then
            return 'HBA'
        elseif work_mode == 'JBOD' then
            return 'JBOD'
        elseif work_mode == 'Mixed' then
            return 'Mixed'
        else
            return 'N/A'
        end
    end
    -- 10进制数转换成2进制
    local function dec2bin(dec)
        local bin = ""
        while dec > 0 do
            bin = tostring(dec%2) .. bin
            dec = math.floor(dec/2)
        end
        return string.format('%s', bin)
    end
    -- 打印RAID控制器的健康状态
    local function get_controller_health(fault_code)
        local res = ''
        if not fault_code or fault_code == 0xFFFF then
            return 'N/A\n'
        end
        if fault_code == 0 then
            return string.format('%s[1;32m%s%s[0m\n', str_char_033, 'Normal', str_char_033)
        end
        res = res .. string.format('%s[1;31m%s%s[0m\n', str_char_033, 'Abnormal', str_char_033)
        res = res .. '\tDetails:\n'
        local fault_code_2bin = dec2bin(fault_code):reverse()
        if string.sub(fault_code_2bin, 1, 1) == '1' then
            res = res .. string.format('\t\t%s\n', 'Memory correctable errors')
        end
        if string.sub(fault_code_2bin, 2, 2) == '1' then
            res = res .. string.format('\t\t%s\n', 'Memory uncorrectable errors')
        end
        if string.sub(fault_code_2bin, 3, 3) == '1' then
            res = res .. string.format('\t\t%s\n', 'Memory ECC errors reached limit')
        end
        if string.sub(fault_code_2bin, 4, 4) == '1' then
            res = res .. string.format('\t\t%s\n', 'NVRAM uncorrectable errors')
        end
        if string.sub(fault_code_2bin, 5, 5) == '1' then
            res = res .. string.format('\t\t%s\n', 'Raid communication loss')
        end
        res = res .. '\n\n'
        return res
    end
    local function get_controller_mem_size(mem_size)
        if mem_size == 0xFFFF then
            return 'N/A'
        else
            return mem_size .. ' MB'
        end
    end
    -- 获取条带大小,默认单位Bytes
    local function get_strip_size(strip_size)
        local capacity_basic_unit = 1024
        if not strip_size then
            return 'N/A'
        elseif strip_size // (capacity_basic_unit * capacity_basic_unit) ~= 0 then
            return strip_size // (capacity_basic_unit * capacity_basic_unit) .. ' MB'
        elseif strip_size // capacity_basic_unit ~= 0 then
            return strip_size // capacity_basic_unit .. ' KB'
        else
            return strip_size .. ' B'
        end
    end
    -- RAID控制器的spare activation mode属性信息
    local function get_controller_spare_activation_mode(spare_activation_mode)
        if spare_activation_mode == 'Predictive' then
            return 'Predictive'
        elseif spare_activation_mode == 'Falure' then
            return 'Failure'
        else
            return 'N/A'
        end
    end
    local function get_controller_pcie_link_width(pcie_link_width)
        if pcie_link_width == 'N/A' then
            return 'N/A'
        else
            return string.sub(pcie_link_width, 1) .. ' bit(s)/link(s)'
        end
    end
    -- RAID控制器的no battery write cache属性信息
    local function get_controller_no_battery_write_cache(no_battery_write_cache)
        if no_battery_write_cache == 0 then
            return 'Disabled'
        elseif no_battery_write_cache == 1 then
            return 'Enabled'
        else
            return 'N/A'
        end
    end
    -- RAID控制器的read cache percent属性信息
    local function get_controller_read_cache_percent(read_cache_percent)
        if read_cache_percent == 0xFF then
            return 'N/A'
        else
            return read_cache_percent .. ' percent'
        end
    end
    local function get_write_cache_policy(policy)
        if string.len(policy) == 0 then
            return 'N/A'
        else
            return policy
        end
    end
    -- RAID控制器cache_pinned的信息
    local function convert_controller_state_common(state)
        if state == 1 then
            return 'Yes'
        elseif state == 0 then
            return 'No'
        else
            return 'N/A'
        end
    end
    local function get_controller_ddr_ecc_count(ddr_ecc_count)
        if ddr_ecc_count == 0xFFFF then
            return 'N/A'
        else
            return ddr_ecc_count
        end
    end
    local function get_controller_ref_bbu_status(bbu_present)
        if type(bbu_present) == 'userdata' then
            return 'N/A'
        end
        if bbu_present == 0 then
            return 'Absent'
        elseif bbu_present == 0xff then
            return 'N/A'
        else
            return 'Present'
        end
    end
    local function print_controller_phy_err_info(phy_list)
        local available = false
        if type(phy_list) ~= 'table' or #phy_list == 0 then
            return
        end
        echo('\nPHY Status                                    : ')
        table.sort(phy_list, function(a, b)
            return a.Id < b.Id
        end)

        for _, item in pairs(phy_list) do
            if item.Id ~= 0xFF then
                echo(string.format('\n\tPHY #%d :\n', item.Id))
                echo(string.format('\t\t%-30s: %d\n', 'Invalid Dword Count', item.InvalidDwordCount))
                echo(string.format('\t\t%-30s: %d\n', 'Loss Dword Sync Count', item.LossDwordSyncCount))
                echo(string.format('\t\t%-30s: %d\n', 'PHY Reset Problem Count', item.PhyResetProblemCount))
                echo(string.format('\t\t%-30s: %d\n', 'Running Disparity Error Count', item.RunningDisparityErrorCount))
                available = true
            end
        end
        if available == false then
            echo('Unavailable\n')
        end
    end

    local function set_invalid_prop_val(prop)
        if type(prop) == 'userdata' then
            return 'N/A'
        end
 
        return prop
    end

    local function get_bbu_error_details(health_status)
        local error_details = ''
        local error_messages = {
            'Voltage low',
            'Battery needs to be replaced',
            'Learn cycle failed',
            'Learn cycle timeout',
            'Pack is about to fail',
            'Remaining capacity low',
            'No space for cache offload'
        }

        for i = 1, #error_messages do
            if health_status and (health_status & (1 << (i - 1))) ~= 0 then
                error_details = error_details .. '\t\t' .. error_messages[i] .. '\n'
            end
        end
    
        return error_details
    end

    -- 打印RAID控制器的BBU状态信息
    local function print_bbu_status(item)
        local normal = true
        local error_details = '' -- 错误信息字符串
        if get_controller_ref_bbu_status(item.BBUState) ~= 'Present' then
            echo('BBU Status                                    : Absent', '\n')
            return
        end
        echo('BBU Status                                    : ' .. get_controller_ref_bbu_status(item.BBUState), '\n')
        echo('BBU Type                                      : ' .. set_invalid_prop_val(item.BBUName), '\n')
        if item.HealthStatus and item.HealthStatus ~= 0 then
            error_details = error_details .. get_bbu_error_details(item.HealthStatus)
            normal = false
        end
        if type(item.BBUName) == 'userdata' then
            echo('BBU Health                                    : ' .. 'N/A', '\n')
        elseif normal == true then
            echo('BBU Health                                    : ' .. string.format('%s[1;32m%s%s[0m\n', str_char_033, 'Normal', str_char_033))
        else
            echo('BBU Health                                    : ' .. string.format('%s[1;31m%s%s[0m\n', str_char_033, 'Abnormal', str_char_033))
            echo('\tDetails:\n')
            echo(error_details, '\n')
        end
    end
    local function print_raid_controller_info(item)
        echo('RAID Controller #' .. item.Id .. ' Information','\n')
        echo('----------------------------------------------------------------------','\n')
        echo('Controller Name                               : ' .. item.Name, '\n')
        echo('Controller Type                               : ' .. item.Type, '\n')
        echo('Component Name                                : ' .. item.DeviceName, '\n')
        echo('Support Out-of-Band Management                : ' .. get_controller_oob_support(item.OOBSupport), '\n')
        echo('Supported RAID Levels                         : ' .. get_supported_raid_level(item.SupportedRAIDTypes), '\n')
        if item.DriverName ~= 'N/A' then
            echo('Controller Driver Name                        : ' .. item.DriverName, '\n')
            echo('Controller Driver Type                        : ' .. item.DriverVersion, '\n')
        end
        if sms_state == 1 and item.OOBSupport ~= 1 then
            return
        end
        echo('Controller Mode                               : ' .. get_controller_work_mode(item.WorkMode), '\n')
        echo('Controller Health                             : ' .. get_controller_health(item.Name ~= 'N/A' and item.FaultCode))
        echo('Firmware Version                              : ' .. item.FirmwareVersion, '\n')
        if dal_test_controller_vendor(item.TypeId, VENDER_LSI) then
            echo('NVDATA Version                                : ' .. item.NVDataVersion, '\n')
        end
        if item.TypeId == PMC_3152_8I_SMART_RAID then
            echo('Hardware Revision                             : ' .. item.HardwareRevision, '\n')
        end
        echo('Memory Size                                   : ' .. get_controller_mem_size(item.MemorySizeMiB), '\n')
        echo('Device Interface                              : ' .. item.DeviceInterface, '\n')
        echo('SAS Address                                   : ' .. item.SASAddr, '\n')
        echo('Minimum Strip Size Supported                  : ' .. get_strip_size(item.Name ~= 'N/A' and item.MinStripSizeBytes), '\n')
        echo('Maximum Strip Size Supported                  : ' .. get_strip_size(item.Name ~= 'N/A' and item.MaxStripSizeBytes), '\n')
        if dal_test_controller_vendor(item.TypeId, VENDER_PMC) then
            echo('Spare Activation Mode                         : ' .. get_controller_spare_activation_mode(item.HotSpareActivationMode), '\n')
        end
        
        if dal_test_controller_vendor(item.TypeId, VENDER_PMC) or dal_test_controller_vendor(item.TypeId, VENDER_HUAWEI) then
            echo('Host bus link Width                           : ' .. get_controller_pcie_link_width(item.PCIeLinkWidth), '\n')
        end
        if dal_test_controller_vendor(item.TypeId, VENDER_PMC) then
            echo('No-Battery Write Cache                        : ' .. get_controller_no_battery_write_cache(item.NoBatteryWriteCacheEnabled), '\n')
            echo('Read Cache Percentage                         : ' .. get_controller_read_cache_percent(item.ReadCachePercent), '\n')
            echo('Configured Drives Write Cache Policy          : ' .. get_write_cache_policy(item.ConfiguredDriveWriteCachePolicy), '\n')
            echo('Unonfigured Drives Write Cache Policy         : ' .. get_write_cache_policy(item.UnconfiguredDriveWriteCachePolicy), '\n')
            echo('HBA Drives Write Cache Policy                 : ' .. get_write_cache_policy(item.HBADriveWriteCachePolicy), '\n')
        end
        if dal_test_controller_vendor(item.TypeId, VENDER_PMC) == false then
            echo('Controller Cache Is Pinned                    : ' .. convert_controller_state_common(item.Name ~= 'N/A' and item.CachePinnedState), '\n')
        end
        
        if dal_test_controller_vendor(item.TypeId, VENDER_LSI) then
            echo('Maintain PD Fail History across Reboot        : ' .. convert_controller_state_common(item.Name ~= 'N/A' and item.MaintainPDFailHistrory), '\n')
        end
        if dal_test_controller_vendor(item.TypeId, VENDER_PMC) == false then
            echo('Copyback Enabled                              : ' .. convert_controller_state_common(item.Name ~= 'N/A' and item.CopyBackState), '\n')
            echo('Copyback on SMART error Enabled               : ' .. convert_controller_state_common(item.Name ~= 'N/A' and item.SmarterCopyBackState), '\n')
            echo('JBOD Enabled                                  : ' .. convert_controller_state_common(item.Name ~= 'N/A' and item.JBODState), '\n')
            echo('DDR ECC Count                                 : ' .. get_controller_ddr_ecc_count(item.DDREccCount), '\n')
        end
        if #item.BootDevices >= 1 then
            echo('Primary Boot Device                           : ' .. item.BootDevices[1], '\n')
        end
        if #item.BootDevices >= 2 and dal_test_controller_vendor(item.TypeId, VENDER_HUAWEI) == false then
            echo('Secondary Boot Device                         : ' .. item.BootDevices[2], '\n')
        end
        print_bbu_status(item)
        if item.TypeId ~= PMC_3152_8I_SMART_RAID then
            print_controller_phy_err_info(item.GetPHYList)
        end
        echo('----------------------------------------------------------------------','\n\n')
    end

    local match_flag = false
    if type(GetControllerList) ~= 'table' or #GetControllerList == 0 then
        io.write('Not found RAID controllers.')
        return
    end
    if Option == 'all' then
        table.sort(GetControllerList, function(a, b)
            return a.Id < b.Id
        end)
        for _, item in pairs(GetControllerList) do
            print_raid_controller_info(item)
        end
    else
        local raid_index = tonumber(Option)
        -- 只能是integer，大于0
        if not raid_index or math.type(raid_index) ~= 'integer' or raid_index < 0 then
            io.write('Invalid RAID controller ID.')
            return
        end
        for _, item in pairs(GetControllerList) do
            if item.Id == raid_index then
                match_flag = true
                print_raid_controller_info(item)
                break
            end
        end
        if match_flag ~= true then
            io.write(string.format('RAID controller ID is out of range[0 to %d].', #GetControllerList - 1))
        end
    end
    echo('\b') -- 消除命令行尾部多的一个空行
%}