-- 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 fru_id_mgmt = require 'fru_management'
local lu = require 'luaunit'
local fru_db = require 'frudata.db'
local mc_utils = require 'mc.utils'
local log = require 'mc.logging'
local test_fru_id_mgmt = {}

local function test_alloted_fru_id(db)
    local obj_pos1 = {des = 1}
    local pos1 = 'pos1'
    local obj_pos2 = {des = 2}
    local pos2 = 'pos2'
    fru_id_mgmt.allot_fruid(obj_pos2, pos2, db)
    lu.assertEquals(obj_pos2.FruId, 52)
    fru_id_mgmt.allot_fruid(obj_pos1, pos1, db)
    lu.assertEquals(obj_pos1.FruId, 51)
    fru_id_mgmt.free_fru_id(pos2, db)
    fru_id_mgmt.allot_fruid(obj_pos2, pos2, db)
    lu.assertEquals(obj_pos2.FruId, 5)

end

function test_fru_id_mgmt:test_fru_id_mgmt()
    local cwd = mc_utils.realpath('.')
    mc_utils.remove_file(cwd .. '/fru.test.db')
    local db = fru_db('./fru.test.db', {})
    local fru_id_obj1 = db.PositionFruIdMapping({Id = 51, Position = 'pos1'})
    fru_id_obj1:save()
    local fru_id_obj2 = db.PositionFruIdMapping({Id = 52, Position = 'pos2'})
    fru_id_obj2:save()
    fru_id_mgmt.init_fru_id(db)
    -- 初始化后数据库被清空查询结果应为nil
    local obj_51 = db:select(db.PositionFruIdMapping):where({Id = 51}):first()
    lu.assertEquals(obj_51, nil)
    local obj1 = {des = 1}
    local obj2 = {des = 2}
    local obj3 = {des = 3}
    local obj4 = {des = 4}
    local obj5 = {des = 5, FruId = 64}
    local obj6 = {des = 6, FruId = 0}
    local obj7 = {des = 5, FruId = 63}
    local pos1 = '1'
    local pos2 = '2'
    local pos3 = '3'
    local pos4 = '4'
    local pos5 = '5'
    -- 同一位置进来不同的obj，分配的id一致
    fru_id_mgmt.allot_fruid(obj1, pos1, db)
    lu.assertEquals(obj1.FruId, 1)
    fru_id_mgmt.allot_fruid(obj2, pos1, db)
    lu.assertEquals(obj2.FruId, 1)
    local db_obj = db:select(db.PositionFruIdMapping):where({Id = 1}):first()
    lu.assertEquals(db_obj.Position, '1')
    fru_id_mgmt.allot_fruid(obj3, pos3, db)
    lu.assertEquals(obj3.FruId, 2)
    fru_id_mgmt.allot_fruid(obj2, pos2, db)
    lu.assertEquals(obj2.FruId, 3)
    -- 释放obj3对应的fruid，模拟删除obj3
    fru_id_mgmt.free_fru_id(pos3, db)
    fru_id_mgmt.allot_fruid(obj4, pos4, db)
    -- 删除后注册应该是空出来的优先使用，期望为2
    lu.assertEquals(obj4.FruId, 2)
    fru_id_mgmt.allot_fruid(obj5, pos4, db)
    -- 边界值和异常分支测试
    lu.assertEquals(obj5.FruId, 64)
    fru_id_mgmt.allot_fruid(obj6, pos4, db)
    lu.assertEquals(obj6.FruId, 0)
    fru_id_mgmt.allot_fruid(obj7, pos5, db)
    lu.assertEquals(obj7.FruId, 4)
    test_alloted_fru_id(db)
    mc_utils.remove_file(cwd .. '/fru.test.db')
end

return test_fru_id_mgmt