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

local lu = require('luaunit')

TestCustomizeConfig = {}

local saved_pkg = {}

local function save_packages(keys)
    for _, k in ipairs(keys) do
        saved_pkg[k] = package.loaded[k]
    end
end

local function restore_packages()
    for k, v in pairs(saved_pkg) do
        if v == nil then
            package.loaded[k] = nil
        else
            package.loaded[k] = v
        end
    end
    saved_pkg = {}
end

local function setup_mocked_customize_config(opts)
    opts = opts or {}
    package.loaded['others.customize_config'] = nil

    local keys = { 'mc.logging', 'drives.drives_object' }
    save_packages(keys)

    -- Mock mc.logging
    local notice_calls = {}
    local operation_calls = {}
    package.loaded['mc.logging'] = {
        debug = function() end,
        info = function() end,
        notice = function(self, fmt, ...)
            table.insert(notice_calls, string.format(fmt, ...))
        end,
        error = function(self, fmt, ...)
            -- error may be called in import tests
        end,
        operation = function(self, ...)
            table.insert(operation_calls, { ... })
        end,
    }

    -- Mock drives.drives_object
    local log_enable = opts.log_auto_collect_enable
    local log_interval = opts.log_auto_collect_interval or 24
    package.loaded['drives.drives_object'] = {
        get_instance = function()
            return {
                obj = {
                    LogAutoCollectEnable = log_enable,
                    LogAutoCollectInterval = log_interval,
                },
                apply_log_auto_collect_enable = function()
                    return true
                end,
                apply_log_collect_interval = function()
                    return true
                end,
            }
        end,
    }

    local module = require('others.customize_config')
    return {
        module = module,
        notice_calls = notice_calls,
        operation_calls = operation_calls,
    }
end

function TestCustomizeConfig:tearDown()
    restore_packages()
    package.loaded['others.customize_config'] = nil
end

-- Covers lines 79, 86, 88, 90: on_export with LogAutoCollectEnable=true
function TestCustomizeConfig:test_on_export_enable_true()
    local ctx = setup_mocked_customize_config({
        log_auto_collect_enable = true,
        log_auto_collect_interval = 24,
    })

    local data = ctx.module.on_export(nil)

    lu.assertNotNil(data)
    lu.assertEquals(data.BMCSet_DrivesLogAutoCollectEnable, 1)
    lu.assertEquals(data.BMCSet_DrivesLogCollectInterval, 24)

    -- Verify log:notice was called for export (lines 86, 90)
    local found_enable = false
    local found_interval = false
    for _, msg in ipairs(ctx.notice_calls) do
        if string.find(msg, 'BMCSet_DrivesLogAutoCollectEnable') then
            found_enable = true
        end
        if string.find(msg, 'BMCSet_DrivesLogCollectInterval') then
            found_interval = true
        end
    end
    lu.assertTrue(found_enable)
    lu.assertTrue(found_interval)
end

-- Covers lines 79, 86, 88, 90: on_export with LogAutoCollectEnable=false (line 83)
function TestCustomizeConfig:test_on_export_enable_false()
    local ctx = setup_mocked_customize_config({
        log_auto_collect_enable = false,
        log_auto_collect_interval = 48,
    })

    local data = ctx.module.on_export(nil)

    lu.assertEquals(data.BMCSet_DrivesLogAutoCollectEnable, 0)
    lu.assertEquals(data.BMCSet_DrivesLogCollectInterval, 48)
end

-- Covers line 92-93: on_export with ctx that has get_initiator
function TestCustomizeConfig:test_on_export_with_ctx()
    local ctx = setup_mocked_customize_config({
        log_auto_collect_enable = true,
    })

    local mock_ctx = {
        get_initiator = function()
            return 'test_user'
        end,
    }

    ctx.module.on_export(mock_ctx)

    -- Verify operation log was called
    lu.assertTrue(#ctx.operation_calls > 0)
end

function TestCustomizeConfig:test_on_export_nil_ctx()
    local ctx = setup_mocked_customize_config({
        log_auto_collect_enable = true,
    })

    -- ctx is nil, should not call operation log
    ctx.module.on_export(nil)

    lu.assertEquals(#ctx.operation_calls, 0)
end