-- Copyright (c) 2026 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 lu = require 'luaunit'
local c_drive = require 'drive.drive_object'
local pd_identify_service = require 'pd.pd_identify_service'
local rpc_service_subhealth = require 'rpc_services.rpc_service_subhealth'
local common_def = require 'common_def'
local drive_collection = require 'drive.drive_collection'
local log = require 'mc.logging'

TestRpcServiceDriveSubhealth = {}

function TestRpcServiceDriveSubhealth:test_get_drive_subhealth()
    local mock_drive = {
        Name = 'nvme0n1',
        FailurePredicted = false,
        on_update_io_diagnose_info = { emit = function() end },
        on_update_diagnose_metric = { emit = function() end }
    }
    
    -- 桩 drive_collection:check_and_get_drive 方法
    local original_check_and_get_drive = drive_collection.check_and_get_drive
    drive_collection.check_and_get_drive = function(collection_self, drive_name)
        if drive_name == 'nvme0n1' then
            return mock_drive
        else
            return nil
        end
    end
    
    -- 桩 log:operation 方法
    local original_log_operation = log.operation
    log.operation = function() end
    
    local mock_ctx = {
        get_initiator = function() return 'test' end
    }
    
    local ras_subhealth_data_info = {
        {
            Key = "DriveName",
            Value = 'nvme0n1',
        },
        {
            Key = "FailurePredicted",
            Value = "1",
        }
    }

    -- 调用被测方法，此方法应该没有返回值，而是直接修改驱动器对象
    rpc_service_subhealth:set_drive_subhealth_diag_result(mock_ctx, ras_subhealth_data_info)

    if original_check_and_get_drive then
        drive_collection.check_and_get_drive = original_check_and_get_drive
    end
    
    if original_log_operation then
        log.operation = original_log_operation
    end
    
    -- 验证驱动器对象的属性已被正确设置
    lu.assertEquals(mock_drive.Name, 'nvme0n1')
    lu.assertEquals(mock_drive.FailurePredicted, true)
end

function TestRpcServiceDriveSubhealth:test_null_param()
    local mock_drive = {
        Name = 'nvme0n1',
        FailurePredicted = nil,
        on_update_io_diagnose_info = { emit = function() end },
        on_update_diagnose_metric = { emit = function() end }
    }
    
    -- 桩 drive_collection:check_and_get_drive 方法
    local original_check_and_get_drive = drive_collection.check_and_get_drive
    drive_collection.check_and_get_drive = function(collection_self, drive_name)
        if drive_name == 'nvme0n1' then
            return mock_drive
        else
            return nil
        end
    end
    
    -- 桩 log:operation 方法
    local original_log_operation = log.operation
    log.operation = function() end
    
    local mock_ctx = {
        get_initiator = function() return 'test' end
    }
    
    local ras_subhealth_data_info = {
        {
            Key = "DriveName",
            Value = 'nvme0n1',
        },
        {
            Key = "FailurePredicted",
            Value = nil,
        }
    }
    -- 调用被测方法，此方法应该没有返回值，而是直接修改驱动器对象
    rpc_service_subhealth:set_drive_subhealth_diag_result(mock_ctx, ras_subhealth_data_info)

    if original_check_and_get_drive then
        drive_collection.check_and_get_drive = original_check_and_get_drive
    end
    
    if original_log_operation then
        log.operation = original_log_operation
    end
    
    -- 验证驱动器对象的属性已被正确设置
    lu.assertEquals(mock_drive.Name, 'nvme0n1')
    lu.assertEquals(mock_drive.FailurePredicted, nil)
end

function TestRpcServiceDriveSubhealth:test_invalid_param()
    local mock_drive = {
        Name = 'nvme0n1',
        FailurePredicted = true,
        on_update_io_diagnose_info = { emit = function() end },
        on_update_diagnose_metric = { emit = function() end }
    }
    
    -- 桩 drive_collection:check_and_get_drive 方法
    local original_check_and_get_drive = drive_collection.check_and_get_drive
    drive_collection.check_and_get_drive = function(collection_self, drive_name)
        if drive_name == 'nvme0n1' then
            return mock_drive
        else
            return nil
        end
    end
    
    -- 桩 log:operation 方法
    local original_log_operation = log.operation
    log.operation = function() end
    
    local mock_ctx = {
        get_initiator = function() return 'test' end
    }
    
    local ras_subhealth_data_info = {
        {
            Key = "DriveName",
            Value = 'nvme0n1',
        },
        {
            Key = "FailurePredicted",
            Value = '5',
        }
    }
    
    local err, _ = pcall(function()
        rpc_service_subhealth:set_drive_subhealth_diag_result(mock_ctx, ras_subhealth_data_info)
    end)

    -- 恢复原始函数
    if original_check_and_get_drive then
        drive_collection.check_and_get_drive = original_check_and_get_drive
    end
    
    if original_log_operation then
        log.operation = original_log_operation
    end

    lu.assertFalse(err)
end