local lu = require 'luaunit'
local c_chassis_db = require 'chassis.db'
local hook_tasks = require 'test_common.hook_tasks'
local super_pod_label_object = require 'super_pod_label_object'
local super_pod_label_collection = require 'super_pod_label_collection'
local object = require 'mc.orm.object'
local business_config = require 'config_mgmt.business_config'
local client = require 'chassis.client'
local ctx = require 'mc.context'
local ipmi = require 'ipmi'
local cc = ipmi.types.Cc
local enums = require 'ipmi.enums'
local channel_type = enums.ChannelType

TestChassisService = {}

function TestChassisService:flush()
    self.database.db:flush()
end

local function construct_db()
    local ok, datas = pcall(require, 'chassis.datas')
    if not ok then
        datas = nil
    end
    local db = c_chassis_db(':memory:', datas)
    return db
end

function TestChassisService:setupClass()
    self.database = construct_db()
    hook_tasks.hook()
    self.bus = {}
    self.app_name = 'ChassisTest'
    self.super_pod_label_collection = super_pod_label_collection.new(self.bus)
    self:flush()
end

function TestChassisService:teardownClass()
end

function TestChassisService:test_set_super_pod_label_enabled()
    local req = {}
    req.Data = 1
    ctx.ChanType = channel_type.CT_ME:value()
    local res = self.super_pod_label_collection:ipmi_set_super_pod_enabled(req, ctx)
    lu.assertEquals(res.CompletionCode, cc.DataNotAvailable)

    local obj = {}
    client:SetFruCtrlObject(obj)
    res = self.super_pod_label_collection:ipmi_set_super_pod_enabled(req, ctx)
    lu.assertEquals(res.CompletionCode, cc.DataNotAvailable)

    client:SetPowerState("OFF")
    res = self.super_pod_label_collection:ipmi_set_super_pod_enabled(req, ctx)
    lu.assertEquals(res.CompletionCode, cc.DataNotAvailable)
    req = {
        Data = {
            byte = function(bit)
                return 0
            end
        }
    }
    local super_pod_label_object = require 'super_pod_label_object'
    super_pod_label_object.collection = {
        find = function()
            return {
                update_super_pod_enabled = function()
                    return true
                end,
                update_super_pod_size = function()
                    return false
                end,
                update_server_index = function()
                    return false
                end,
                update_super_pod_id = function()
                    return false
                end,
                set_superPod_label = function()
                    return false
                end,
                TopologyType = 0,
                UBMDeployMode = 0,
                ChassisId = 0,
                IsUBFabricMode= 0,
                IsUBControlNode = 0
            }
        end
    }
    local ok = pcall(function (...)
        self.super_pod_label_collection:ipmi_set_super_pod_enabled(req, ctx)
    end)
    lu.assertEquals(ok, true)
    client:RestoreDefault()
end

function TestChassisService:test_get_super_pod_label_enabled()
    local req = {}
    req.Data = 1
    ctx.ChanType = channel_type.CT_ME:value()
    local res = self.super_pod_label_collection:ipmi_get_super_pod_enabled(req, ctx)
    lu.assertEquals(res.CompletionCode, cc.DataNotAvailable)
end

function TestChassisService:test_super_pod_label()
    local ok
    package.loaded['super_pod_label_object'] = nil
    package.loaded['super_pod_label_collection'] = nil
    package.loaded['config_mgmt.business_config'] = nil
    local super_pod_label_collection = require 'super_pod_label_collection'
    local super_pod_label_object = require 'super_pod_label_object'
    super_pod_label_object.collection = {
        find = function()
            return {
                update_super_pod_enabled = function()
                    error()
                end,
                update_super_pod_size = function()
                    return false
                end,
                update_server_index = function()
                    return false
                end,
                update_super_pod_id = function()
                    return false
                end,
                set_superPod_label = function()
                    return false
                end,
                TopologyType = 0,
                UBMDeployMode = 0,
                ChassisId = 0,
                IsUBFabricMode= 0,
                IsUBControlNode = 0
            }
        end
    }
    self.super_pod_label_collection = super_pod_label_collection.new(self.bus)
    local business_config = require 'config_mgmt.business_config'
    ok = pcall(business_config.on_import, nil, ctx, {
        SuperPodLabel = {
            SuperPodId = {
                Value = 1
            }
        }
    })
    lu.assertEquals(ok, false)
    ok = pcall(business_config.on_import, nil, ctx, {
        SuperPodLabel = {
            SuperPodSize = {
                Value = 1
            },
        }
    })
    lu.assertEquals(ok, false)
    ok = pcall(business_config.on_import, nil, ctx, {
        SuperPodLabel = {
            ServerIndex = {
                Value = 1
            },
        }
    })
    lu.assertEquals(ok, false)
    ok = pcall(business_config.on_import, nil, ctx, {
        SuperPodLabel = {
            TopologyType = {
                Value = 1
            },
            UBMDeployMode = {
                Value = 1
            },
            PresentDPUCount = {
                Value = 32
            },
        }
    })
    lu.assertEquals(ok, true)
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodEnabled(ctx, false)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodId(ctx, 5)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodSize(ctx, 5)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function()
        self.super_pod_label_collection:SetServerIndex(ctx, 5)
    end)
    lu.assertEquals(ok, false)
    local superpod_labels = {
        {Key = 'TopologyType', Value = 0}
    }
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodLabel(ctx, 3, superpod_labels)
    end)
    lu.assertEquals(ok, true)
    superpod_labels[1].Key = 'IsUBFabricMode'
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodLabel(ctx, 3, superpod_labels)
    end)
    lu.assertEquals(ok, true)
    superpod_labels[1].Value = nil
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodLabel(ctx, 3, superpod_labels)
    end)
    lu.assertEquals(ok, true)
    local req = {
        Data = {
            byte = function(bit)
                return 0
            end
        }
    }
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_get_superpod_label_info(req)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info(req)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_super_pod_id(req)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_server_index(req)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_super_pod_enabled(req)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_get_super_pod_enabled(req)
    end)
    lu.assertNotNil(ok)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_super_pod_size(req)
    end)
    lu.assertEquals(ok, false)
    local c_super_pod_label_collection = self.super_pod_label_collection
    self.super_pod_label_collection.TopologyType = 0
    self.super_pod_label_collection.IsUBFabricMode = 0
    self.super_pod_label_collection.IsUBControlNode = 0
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_get_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, true)
    req.Length = 0x00
    req.Data = '\x01\x00\x01\x10'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Length = 0xff
    req.Data = '\x01\x05\x02\x07\x08'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Data = '\x01\x09\x01\x07'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Data = '\x01\x06'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Data = '\x01\x05\x01\x07'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Data = '\x01\x06\x01\x02'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Data = '\x01\x00\x01\x04'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Data = '\x01\x04\x01\x07'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    req.Data = '\x01\x06\x01\x01'
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Data = '\x01\x00\x01\x00'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Data = '\x00'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    req.Data = '\x07'
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion(req)
    end)
    lu.assertEquals(ok, false)
    self.super_pod_label_collection = c_super_pod_label_collection
end

function TestChassisService:test_super_pod_label_collection()
    local ok
    package.loaded['super_pod_label_object'] = nil
    package.loaded['super_pod_label_collection'] = nil
    package.loaded['config_mgmt.business_config'] = nil
    local super_pod_label_collection = require 'super_pod_label_collection'
    local super_pod_label_object = require 'super_pod_label_object'
    super_pod_label_object.collection = {
        find = function()
            return nil
        end
    }
    local business_config = require 'config_mgmt.business_config'
    ok = pcall(business_config.on_import, nil, ctx, {
        SuperPodLabel = {
            SuperPodSize = {
                Value = 1
            },
        }
    })
    lu.assertEquals(ok, false)
    ok = pcall(business_config.on_import, nil, ctx, {
        SuperPodEnabled = {
            Value = false
        }
    })
    lu.assertEquals(ok, false)
    self.super_pod_label_collection = super_pod_label_collection.new(self.bus)
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodEnabled(ctx, false)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodId(ctx, 5)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodSize(ctx, 5)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function()
        self.super_pod_label_collection:SetServerIndex(ctx, 5)
    end)
    lu.assertEquals(ok, false)
    local superpod_labels = {
        {Key = 'TopologyType', Value = 0}
    }
    ok = pcall(function()
        self.super_pod_label_collection:SetSuperPodLabel(ctx, 3, superpod_labels)
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_get_superpod_label_info()
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info()
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_super_pod_id()
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_server_index()
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_super_pod_enabled()
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_get_super_pod_enabled()
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_super_pod_size()
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_get_superpod_label_info_expansion()
    end)
    lu.assertEquals(ok, false)
    ok = pcall(function ()
        self.super_pod_label_collection:ipmi_set_superpod_label_info_expansion()
    end)
    lu.assertEquals(ok, false)
end