{%
    local LEVEL_NORMAL = 0
    local LEVEL_WARNING = 1
    local LEVEL_CRITICAL = 2
    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 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_logical_drive_raid_level(raid_level)
        -- 0: RAID0
        -- 1: RAID1
        -- 2: RAID2
        -- 3: RAID3
        -- 4: RAID4
        -- 5: RAID5
        -- 6: RAID6
        -- 10: RAID10
        -- 11: RAID1ADM
        -- 12: RAID10ADM
        -- 17: RAID1E
        -- 20: RAID20
        -- 30: RAID30
        -- 40: RAID40
        -- 50: RAID50
        -- 60: RAID60
        -- 255: Unknown
        -- other: reserved
        if raid_level == 17 then
            return 'RAID1(1E)'
        elseif raid_level == 11 then
            return 'RAID1(ADM)'
        elseif raid_level == 12 then
            return 'RAID10(ADM)'
        elseif raid_level == 13 then
            return 'RAID1Triple'
        elseif raid_level == 14 then
            return 'RAID10Triple'
        elseif raid_level == 0xFF then
            return 'N/A'
        else
            return 'RAID' .. raid_level
        end
    end
    local function sml_ld_state2str(drive_status)
        local g_ld_state_desc = {
            {"Partially degraded", LEVEL_WARNING},
            {"Degraded", LEVEL_WARNING},
            {"Optimal", LEVEL_NORMAL},
            {"Failed", LEVEL_CRITICAL},
            {"Not Configured", LEVEL_WARNING},
            {"Interim recovery", LEVEL_WARNING},
            {"Ready for recovery", LEVEL_WARNING},
            {"Recovering", LEVEL_WARNING},
            {"Wrong drive replaced", LEVEL_WARNING},
            {"Drive improperly connected", LEVEL_WARNING},
            {"Expanding", LEVEL_WARNING},
            {"Not available", LEVEL_WARNING},
            {"Queued for expansion", LEVEL_WARNING},
            {"Disabled from SCSI conflict", LEVEL_CRITICAL},
            {"Ejected", LEVEL_WARNING},
            {"Erase in progress", LEVEL_WARNING},
            {"Unused", LEVEL_NORMAL},
            {"Ready to perform predictive spare rebuild", LEVEL_NORMAL},
            {"RPI in progress", LEVEL_WARNING},
            {"RPI queued", LEVEL_WARNING},
            {"Encrypted without key", LEVEL_NORMAL},
            {"Encryption migration", LEVEL_NORMAL},
            {"Encrypted & re-keying", LEVEL_NORMAL},
            {"Encrypted with encryption off", LEVEL_CRITICAL},
            {"Volume encode requested", LEVEL_NORMAL},
            {"Encrypted with re-key request", LEVEL_NORMAL},
            {"Unsupported", LEVEL_CRITICAL},
            {"Not Formatted", LEVEL_NORMAL},
            {"Formatting", LEVEL_NORMAL},
            {"Sanitizing", LEVEL_NORMAL},
            {"Initializing", LEVEL_NORMAL},
            {"Initialize fail", LEVEL_NORMAL},
            {"Deleting", LEVEL_NORMAL},
            {"Delete fail", LEVEL_NORMAL},
            {"Write protect", LEVEL_NORMAL},
        }
        g_ld_state_desc [0] = {}
        g_ld_state_desc[0][1] = 'Offline'
        g_ld_state_desc[0][2] = LEVEL_CRITICAL
        if g_ld_state_desc[drive_status] then
            return g_ld_state_desc[drive_status][2], g_ld_state_desc[drive_status][1]
        else
            return 'N/A', 'N/A'
        end
    end
    -- 获取逻辑盘的状态
    local function get_logical_drive_status(drive_status)
        local level, desc = sml_ld_state2str(drive_status)
        local str_char_033 = string.char(0x1b)
        if level == LEVEL_NORMAL then
            return string.format('%s[1;32m%s%s[0m', str_char_033, desc, str_char_033) -- 浅绿
        elseif level == LEVEL_WARNING then
            return string.format('%s[1;33m%s%s[0m', str_char_033, desc, str_char_033)  -- 黄
        elseif level == LEVEL_CRITICAL then
            return string.format('%s[1;31m%s%s[0m', str_char_033, desc, str_char_033)  -- 浅红
        else
            return string.format('%s\n', desc)
        end
    end

    local LD_POLICY_STR = {
        ["NoReadAhead"] = 'No Read Ahead',
        ["ReadAhead"] = 'Read Ahead',
        ["ReadAheadAdaptive"] = 'Read Ahead Adaptive',

        ["WriteThrough"] = 'Write Through',
        ["WriteBackWithBBU"] = 'Write Back with BBU',
        ["WriteBack"] = 'Write Back',

        ["CachedIO"] = 'Cached IO',
        ["DirectIO"] = 'Direct IO',

        ["ReadWrite"] = "Read Write",
        ["ReadOnly"] = "Read Only",
        ["Blocked"] = "Blocked",
        ["Hidden"] = "Hidden",
    }
    -- 返回逻辑盘的策略
    local function get_logical_drive_policy(policy)
        if string.len(policy) == 0 then
            return 'N/A'
        elseif LD_POLICY_STR[policy] then
            return LD_POLICY_STR[policy]
        else
            return policy
        end
    end
    -- 获取逻辑盘的条带大小,默认单位Bytes
    local function get_logical_drive_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
    -- 获取容量大小，根据容量大小自动选择单位
    local function get_capacity(size)
        local capacity_basic_unit = 1024
        local STORAGE_INFO_INVALID_DWORD = 0xFFFFFFFF
        size = size / (capacity_basic_unit * capacity_basic_unit)
        if size == STORAGE_INFO_INVALID_DWORD then
            return 'N/A'
        elseif size < capacity_basic_unit then -- 小于1TB
            return string.format('%d MB', size)
        elseif size < capacity_basic_unit * capacity_basic_unit then -- 小于1TB
            return string.format('%.3f GB', size / capacity_basic_unit)
        elseif size < capacity_basic_unit * capacity_basic_unit * capacity_basic_unit then -- 小于1PB
            return string.format('%.3f TB', size / (capacity_basic_unit * capacity_basic_unit))
        else
            return string.format('%.3f PB', size / (capacity_basic_unit * capacity_basic_unit * capacity_basic_unit))
        end
    end
    local function get_logical_drive_disk_cache_state(disk_cache_policy)
        if disk_cache_policy == 0 then
            return "Disk's Default"
        elseif disk_cache_policy == 1 then
            return 'Enabled'
        elseif disk_cache_policy == 2 then
            return 'Disabled'
        else
            return 'N/A'
        end
    end
    -- 获取逻辑盘的初始化操作方式
    local function get_logical_drive_init_state(init_state)
        if init_state == 0 then
            return 'No Init'
        elseif init_state == 1 then
            return 'Quick Init'
        elseif init_state == 2 then
            return 'Full Init'
        else
            return 'N/A'
        end
    end
    -- 获取逻辑盘的一致性校验状态
    local function get_logical_drive_cc_state(cc_state)
        if cc_state == 1 then
            return 'Yes'
        elseif cc_state == 0 then
            return 'No'
        else
            return 'N/A'
        end
    end
    local function get_logical_drive_bgi_state(bgi_state)
        if bgi_state == 1 then
            return 'Yes'
        elseif bgi_state == 0 then
            return 'No'
        else
            return 'N/A'
        end
    end
    -- 是否是启动盘
    local function get_drive_bootable(bootable)
        if bootable > 0 then
            return 'Yes'
        elseif bootable == 0 then
            return 'No'
        else
            return 'N/A'
        end
    end
    -- 启动盘优先级
    local function get_drive_boot_priority(boot_priority)
        if boot_priority == 0 then
            return 'None'
        elseif boot_priority == 1 then
            return 'Primary'
        elseif boot_priority == 2 then
            return 'Secondary'
        elseif boot_priority == 3 then
            return 'All'
        else
            return 'N/A'
        end
    end
    -- 逻辑盘是否是SSCD
    local function get_logical_drive_isSSCD(isSSCD)
        if isSSCD == 1 then
            return 'Yes'
        elseif isSSCD == 0 then
            return 'No'
        else
            return 'N/A'
        end
    end
    -- 普通逻辑盘是否关联了CacheCade LD
    local function get_logical_drive_sscd_caching_enable(sscd_caching_enable)
        if sscd_caching_enable == 1 then
            return 'Yes'
        elseif sscd_caching_enable == 0 then
            return 'No'
        else
            return 'N/A'
        end
    end
    -- 查看CacheCade逻辑盘关联的普通逻辑盘列表
    local function get_logical_drive_sscd_accociated_ld_list(associated_volumes)
        if #associated_volumes <= 0 then
            return 'N/A'
        end

        local ld_list = ''
        for _, id in ipairs(associated_volumes) do
            ld_list = ld_list .. tostring(id) .. ','
        end

        return ld_list:sub(1, -2)
    end
    -- 组成逻辑盘的物理盘
    local function get_pd_list_participating_in_ld(pd_list)
        local string_buff = {}
        for k,v in pairs(pd_list) do
            local val = v:sub(5)
            table.insert(string_buff, val)
            table.insert(string_buff, ',')
        end
        local str_res = table.concat(string_buff)
        return str_res:sub(1, #str_res - 1)
    end
    -- 逻辑盘的热备盘列表
    local function get_ld_hotspare_list(hotspare_list)
        local string_buff = {}
        for k,v in pairs(hotspare_list) do
            local val = v:sub(5)
            table.insert(string_buff, val)
            table.insert(string_buff, ',')
        end
        if #string_buff == 0 then
            return 'N/A'
        else
            local str_res = table.concat(string_buff)
            return str_res:sub(1, #str_res - 1)
        end
    end
    -- 逻辑盘的加速方法
    local function get_logical_drive_accelerator(acceleration_method)
        if acceleration_method == 'None' then
            return 'None'
        elseif acceleration_method == 'ControllerCache' then
            return 'ControllerCache'
        elseif acceleration_method == 'IOBypass' then
            return 'IOBypass'
        elseif acceleration_method == 'maxCache' then
            return 'maxCache'
        else
            return 'Unknown'
        end
    end
    -- 逻辑盘的缓存行大小
    local function get_logical_drive_cache_line_size(cacheline_sizekib)
        if cacheline_sizekib == 1 then
            return '64KB'
        elseif cacheline_sizekib == 4 then
            return '256KB'
        else
            return 'Unknown'
        end
    end
    -- 逻辑盘的重构状态
    local function get_rebuild_state(rebuild_state, rebuild_progress)
        if rebuild_state == 0xFF then
            return 'N/A'
        end
        if rebuild_state == 0 then
            return 'No'
        elseif rebuild_state == 1 then
            if rebuild_progress == 0xFF then
                return "Yes (Unknown Progress)"
            else
                return string.format("%s (%d%%)", "Yes", rebuild_progress)
            end
        else
            return 'Unknown'
        end
    end
    -- 获取span depth
    local function get_ld_span_depth(disk_array_list)
        local depth = 0
        for _, v in pairs(disk_array_list) do
            if v >= 0x8000 then
                depth = depth + 1
            end
        end

        depth = depth == 0 and #disk_array_list or depth
        return depth
    end

    local function get_drive_number_per_span(item)
        local depth = get_ld_span_depth(item.RefDiskArrayList)
        if depth == 0 then
            return 0
        end

        return #item.RefDriveList // depth
    end

    function printData(item)
        echo('Logical Drive Information:', '\n')
        echo('----------------------------------------------------------------------\n')
        echo('Target ID                                : ' .. item.Id .. '\n')
        echo('Name                                     : ' .. item.VolumeName .. '\n')
        echo('Type                                     : ' .. get_logical_drive_raid_level(item.RAIDType) .. '\n')
        echo('State                                    : ' .. get_logical_drive_status(item.State) .. '\n')
        echo('Default Read Policy                      : ' .. get_logical_drive_policy(item.DefaultReadPolicy) .. '\n')
        echo('Default Write Policy                     : ' .. get_logical_drive_policy(item.DefaultWritePolicy) .. '\n')
        echo('Default Cache Policy                     : ' .. get_logical_drive_policy(item.DefaultCachePolicy) .. '\n')
        echo('Current Read Policy                      : ' .. get_logical_drive_policy(item.CurrentReadPolicy) .. '\n')
        echo('Current Write Policy                     : ' .. get_logical_drive_policy(item.CurrentWritePolicy) .. '\n')
        echo('Current Cache Policy                     : ' .. get_logical_drive_policy(item.CurrentCachePolicy) .. '\n')
        echo('Access Policy                            : ' .. get_logical_drive_policy(item.AccessPolicy) .. '\n')
        echo('Span depth                               : ' .. get_ld_span_depth(item.RefDiskArrayList) .. '\n')
        echo('Number of drives per span                : ' .. get_drive_number_per_span(item) .. '\n')
        echo('Strip Size                               : ' .. get_logical_drive_strip_size(item.OptimumIOSizeBytes) .. '\n')
        echo('Total Size                               : ' .. get_capacity(item.CapacityBytes) .. '\n')
        if dal_test_controller_vendor(item.TypeId, VENDER_PMC) == false then
            echo('Disk Cache Policy                        : ' .. get_logical_drive_disk_cache_state(item.DriveCachePolicy) .. '\n')
            if dal_test_controller_vendor(item.TypeId, VENDER_LSI) then
                echo('Init State                               : ' .. get_logical_drive_init_state(item.InitializationMode) .. '\n')
                echo('Consistency Checking                     : ' .. get_logical_drive_cc_state(item.ConsistencyCheck) .. '\n')
                echo('BGI Enabled                              : ' .. get_logical_drive_bgi_state(item.BGIEnable) .. '\n')
            end
        end
        echo('Bootable                                 : ' .. get_drive_bootable(item.BootEnable) .. '\n')
        echo('Boot Priority                            : ' .. get_drive_boot_priority(item.BootPriority) .. '\n')
        if dal_test_controller_vendor(item.TypeId, VENDER_HUAWEI) == false then
            echo('Uesd for Secondary Cache                     : ' .. get_logical_drive_isSSCD(item.SSDCachecadeVolume) .. '\n')
            if item.SSDCachecadeVolume == 0 then
                echo('SSCD Caching Enable                      : ' .. get_logical_drive_sscd_caching_enable(item.SSDCachingEnable) .. '\n')
            end
            if item.SSDCachecadeVolume == 1 then
                echo('SSCD Associated LD List(ID#)             : ' .. get_logical_drive_sscd_accociated_ld_list(item.AssociatedVolumes) .. '\n')
            end
        end
        echo('OS Letter                                : ' .. item.OSDriveName  .. '\n')
        echo('PD participating in LD (ID#)             : ' .. get_pd_list_participating_in_ld(item.RefDriveList)  .. '\n')
        echo('Dedicated Hot Spare PD (ID#)             : ' .. get_ld_hotspare_list(item.HotSpareDriveList) .. '\n')
        if dal_test_controller_vendor(item.TypeId, VENDER_PMC) then
            echo('Acceleration Method                      : ' .. get_logical_drive_accelerator(item.AccelerationMethod) .. '\n')
            if item.SSDCachecadeVolume ~= 0 then
                echo('Cache Line Size                          : ' .. get_logical_drive_cache_line_size(item.CacheLineSizeKiB) .. '\n')
            end
            echo('Rebuild in Progress                      : ' .. get_rebuild_state(item.RebuildState, item.RebuildProgress) .. '\n')
        end
        echo('----------------------------------------------------------------------\n\n')
    end
    if not ControllerList or #ControllerList == 0 then
        io.write('Not found RAID controller.')
        return
    end

    local max_ctrl_idx = #ControllerList - 1
    if CtrlId < 0 or CtrlId > max_ctrl_idx then
        io.write(string.format('RAID controller index out of range[0 to %d].', max_ctrl_idx))
        return
    end

    if option == 'all' then
        local match_flag = false
        table.sort(GetVolumeList, function(a, b)
            return a.Id < b.Id
        end)
        for _, item in pairs(GetVolumeList) do
            -- 此逻辑盘对象归属于当前指定的RAID卡对象
            if item.RefControllerId == CtrlId then
                match_flag = true
                printData(item)
            end
        end
        if match_flag == false then
            io.write('Not Found Logical Drive.')
            return
        end
        echo('\b') -- 消除一个空行
    else
        local match_flag = false
        local option_to_integer = tonumber(option)
        if not option_to_integer or math.type(option_to_integer) ~= 'integer' or option_to_integer < 0 or option_to_integer > 0xFFFF then
            io.write('Invalid Logical Drive Target Id.')
            return
        end
        if not GetVolumeList or #GetVolumeList == 0 then
            io.write('Not Found Logical Drive.')
            return
        end
        for _, item in pairs(GetVolumeList) do
            -- 此逻辑盘对象归属于当前指定的RAID卡对象
            if item.Id == option_to_integer and item.RefControllerId == CtrlId then
                match_flag = true
                printData(item)
                echo('\b') -- 消除一个空行
                break
            end
        end
        if match_flag == false then
            io.write(string.format('Invalid Logical Drive Target Id : %d', option_to_integer))
        end
    end
%}