-- 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 lu = require('luaunit')
local drives_object = require('drives.drives_object')

TestDrivesObject = {}

local function new_signal()
    return {
        _cb = nil,
        on = function(self, cb)
            self._cb = cb
        end,
    }
end

local function new_storage_app_stub(db)
    local obj = {
        property_changed = new_signal(),
    }
    return {
        db = db,
        CreateDrives = function()
            return obj
        end,
        _drives_obj = obj,
    }
end

function TestDrivesObject:test_log_auto_collect_enable_persist_to_db()
    local saved = {}
    local record = {
        save = function(self)
            saved.LogAutoCollectEnable = self.LogAutoCollectEnable
            saved.saved = true
        end,
    }
    local db = {
        tables = {
            t_drives_info = function(query)
                lu.assertEquals(query, { Id = 0 })
                return record
            end,
        },
        DrivesTableInfo = function()
            return { save = function() end, IsAlerted = false, TemperatureCelsius = 0 }
        end,
    }

    local app = new_storage_app_stub(db)
    local inst = (drives_object.get_instance and drives_object.get_instance(app)) or drives_object.new(app)
    inst.storage_app_service = app
    inst.db = db
    inst.obj = nil
    inst:init()

    app._drives_obj.property_changed._cb('LogAutoCollectEnable', true)
    lu.assertTrue(saved.saved)
    lu.assertEquals(saved.LogAutoCollectEnable, true)
end

function TestDrivesObject:test_log_auto_collect_interval_persist_to_db()
    local saved = {}
    local record = {
        save = function(self)
            saved.LogAutoCollectInterval = self.LogAutoCollectInterval
            saved.saved = true
        end,
    }
    local db = {
        tables = {
            t_drives_info = function(query)
                lu.assertEquals(query, { Id = 0 })
                return record
            end,
        },
        DrivesTableInfo = function()
            return { save = function() end, IsAlerted = false, TemperatureCelsius = 0 }
        end,
    }

    local app = new_storage_app_stub(db)
    local inst = (drives_object.get_instance and drives_object.get_instance(app)) or drives_object.new(app)
    inst.storage_app_service = app
    inst.db = db
    inst.obj = nil
    inst:init()

    app._drives_obj.property_changed._cb('LogAutoCollectInterval', 24)
    lu.assertTrue(saved.saved)
    lu.assertEquals(saved.LogAutoCollectInterval, 24)
end

local function make_ctx()
    return {
        get_initiator = function()
            return {}
        end,
    }
end

function TestDrivesObject:test_apply_log_auto_collect_enable()
    local app = new_storage_app_stub({})
    local inst = drives_object.new(app)
    inst.obj = { LogAutoCollectEnable = false }

    lu.assertTrue(inst:apply_log_auto_collect_enable(true))
    lu.assertEquals(inst.obj.LogAutoCollectEnable, true)

    lu.assertTrue(inst:apply_log_auto_collect_enable(1))
    lu.assertEquals(inst.obj.LogAutoCollectEnable, true)

    lu.assertTrue(inst:apply_log_auto_collect_enable(false))
    lu.assertEquals(inst.obj.LogAutoCollectEnable, false)

    lu.assertTrue(inst:apply_log_auto_collect_enable(0))
    lu.assertEquals(inst.obj.LogAutoCollectEnable, false)

    lu.assertFalse(inst:apply_log_auto_collect_enable('invalid'))
    lu.assertFalse(inst:apply_log_auto_collect_enable(2))
end

function TestDrivesObject:test_apply_log_collect_interval_invalid()
    local app = new_storage_app_stub({})
    local inst = drives_object.new(app)
    inst.obj = { LogAutoCollectInterval = 24 }

    lu.assertFalse(inst:apply_log_collect_interval(0))
    lu.assertFalse(inst:apply_log_collect_interval(256))
    lu.assertEquals(inst.obj.LogAutoCollectInterval, 24)
end

function TestDrivesObject:test_customize_config_on_import()
    local customize_config = require('others.customize_config')
    local app = new_storage_app_stub({})
    local inst = (drives_object.get_instance and drives_object.get_instance(app)) or drives_object.new(app)
    inst.obj = {
        LogAutoCollectEnable = true,
        LogAutoCollectInterval = 24,
    }
    local ok = pcall(customize_config.on_import, make_ctx(), {
        BMCSet_DrivesLogAutoCollectEnable = { Value = 0 },
        BMCSet_DrivesLogCollectInterval = { Value = 12 },
    })
    lu.assertTrue(ok)
    lu.assertEquals(inst.obj.LogAutoCollectEnable, false)
    lu.assertEquals(inst.obj.LogAutoCollectInterval, 12)
end