-- Copyright (c) 2026 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.

local lu = require 'luaunit'

local common_def = require 'common_def'
local controller_collection = require 'controller.controller_collection'
local drive_collection = require 'drive.drive_collection'
local method_misc = require 'method_misc'
local volume_param_check = require 'volume.volume_param_check'

TestVolumeParamCheck = {}

function TestVolumeParamCheck:setUp()
    self._orig_get_ctrl = controller_collection.get_by_controller_id
    self._orig_get_drive = drive_collection.get_drive_by_id
    self._orig_check_name = method_misc.check_volume_name
end

function TestVolumeParamCheck:tearDown()
    if self._orig_get_ctrl then controller_collection.get_by_controller_id = self._orig_get_ctrl end
    if self._orig_get_drive then drive_collection.get_drive_by_id = self._orig_get_drive end
    if self._orig_check_name then method_misc.check_volume_name = self._orig_check_name end
end

function TestVolumeParamCheck:test_check_ld_capacity_invalid_and_valid()
    lu.assertFalse(volume_param_check:check_ld_capacity(0, common_def.SML_LD_CAPACITY_UNIT_MB))
    lu.assertFalse(volume_param_check:check_ld_capacity(0x400000, common_def.SML_LD_CAPACITY_UNIT_GB))
    lu.assertFalse(volume_param_check:check_ld_capacity(0x1000, common_def.SML_LD_CAPACITY_UNIT_TB))
    lu.assertFalse(volume_param_check:check_ld_capacity(1, 0xFF))
    lu.assertTrue(volume_param_check:check_ld_capacity(1, common_def.SML_LD_CAPACITY_UNIT_MB))
end

function TestVolumeParamCheck:test_check_ld_strip_size_with_limits()
    controller_collection.get_by_controller_id = function(_, _)
        return {
            MinStripSizeBytes = 1024,
            MaxStripSizeBytes = 4096
        }
    end
    lu.assertTrue(volume_param_check:check_ld_strip_size(1, 1))   -- 1024
    lu.assertTrue(volume_param_check:check_ld_strip_size(1, 3))   -- 4096
    lu.assertFalse(volume_param_check:check_ld_strip_size(1, 0))  -- 512 < min
end

function TestVolumeParamCheck:test_check_ld_policy_with_vendor_bypass_and_list()
    controller_collection.get_by_controller_id = function(_, _)
        return {
            ReadPolicyWritable = true,
            DefaultReadPolicy = 0,
            SupportedReadPolicyList = { common_def.READ_POLICY_LIST[0] },
            DriveCachePolicyWritable = true,
            DefaultDriveCachePolicy = 0,
            SupportedDriveCachePolicyList = { common_def.DRIVE_CACHE_POLICY_LIST[0] }
        }
    end

    -- vendor bypass: VENDER_PMC for DriveCachePolicy
    volume_param_check.test_controller_vendor_by_ctrl_id = function(_, _, vendor)
        return vendor == common_def.VENDER_PMC
    end
    lu.assertTrue(volume_param_check:check_ld_policy(1, 'DriveCachePolicy', 1))

    -- normal policy list check (no vendor bypass)
    volume_param_check.test_controller_vendor_by_ctrl_id = function() return false end
    lu.assertTrue(volume_param_check:check_ld_policy(1, 'ReadPolicy', 0))
end

function TestVolumeParamCheck:test_check_and_get_span_depth_and_drive_count()
    -- RAID10 + PMC, span_depth 无效字节 → 根据盘数推导
    volume_param_check.test_controller_vendor_by_ctrl_id = function(_, _, vendor)
        return vendor == common_def.VENDER_PMC
    end
    local span = volume_param_check:check_and_get_ld_span_depth(
        1, common_def.RAID_LEVEL_10, 8, common_def.STORAGE_INFO_INVALID_BYTE)
    lu.assertEquals(span, 4)

    -- RAID1 非 PMC，奇数盘失败
    volume_param_check.test_controller_vendor_by_ctrl_id = function() return false end
    lu.assertFalse(volume_param_check:check_drive_count_by_ctrl(1, common_def.RAID_LEVEL_1, 3))
    lu.assertTrue(volume_param_check:check_drive_count_by_ctrl(1, common_def.RAID_LEVEL_1, 4))
end

function TestVolumeParamCheck:test_check_ld_data_created_in_new_array_raid0_and_non0()
    controller_collection.get_by_controller_id = function(_, _)
        return {
            TypeId = 1,
            MinStripSizeBytes = common_def.STORAGE_INFO_INVALID_DWORD,
            MaxStripSizeBytes = common_def.STORAGE_INFO_INVALID_DWORD
        }
    end
    method_misc.check_volume_name = function(_, name, _)
        return name == 'ok' and common_def.SM_CODE_SUCCESS or common_def.SM_CODE_PARA_DATA_ILLEGAL
    end
    drive_collection.get_drive_by_id = function(_, _)
        return { BlockSizeBytes = 4096 }
    end

    -- RAID0: 关注不会返回 RAID 级别相关错误
    local ret = volume_param_check:check_ld_data_created_in_new_array(
        1, string.char(1, 2), common_def.RAID_LEVEL_0, 1, 'ok', 1,
        common_def.SML_LD_CAPACITY_UNIT_MB, 0, 0, 0, 0, 0, 0, 0)
    lu.assertNotEquals(ret, common_def.SM_CODE_INVALID_RAID_LEVEL)
end

