-- 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 Databases = require 'database'
local Col = require 'database.column'

local DPUCard = require 'general_hardware.json_types.DPUCard'
local System = require 'general_hardware.json_types.System'
local def_types = require 'class.types.types'

---@class CpldValidatingTable: Table
---@field SystemId FieldBase
---@field ValidatingCpldFlag FieldBase

---@class SecurityModuleTable: Table
---@field Presence FieldBase
---@field Health FieldBase
---@field Protocol FieldBase
---@field Manufacturer FieldBase
---@field ProtocolVersion FieldBase
---@field FirmwareVersion FieldBase
---@field Id FieldBase

---@class DPUCardTable: Table
---@field BootSourceOverrideMode FieldBase
---@field PxeOption FieldBase
---@field UUID FieldBase
---@field BootSourceOverrideEnabled FieldBase
---@field M2SlotMaxCount FieldBase
---@field NetworkAdapterMaxCount FieldBase
---@field Model FieldBase
---@field SystemLoadedStatus FieldBase
---@field SRVersion FieldBase
---@field UID FieldBase
---@field MRCLogLevel FieldBase
---@field UEFILogLevel FieldBase
---@field LogicVersion FieldBase
---@field MultiLogicVersion FieldBase
---@field CPLDCount FieldBase
---@field PowerState FieldBase
---@field MPUBusyStatus FieldBase
---@field VrdVersion FieldBase
---@field OSSupported FieldBase
---@field StorageIpAddr FieldBase
---@field StorageIpVlan FieldBase
---@field M2SlotPresence FieldBase
---@field NetworkAdapterPresence FieldBase
---@field MCUVersion FieldBase
---@field PfMacInfo FieldBase
---@field Name FieldBase
---@field SlotID FieldBase
---@field PCIeModel FieldBase
---@field DeviceName FieldBase
---@field FunctionClass FieldBase
---@field Description FieldBase
---@field PcbVersion FieldBase
---@field BoardID FieldBase
---@field BoardName FieldBase
---@field VendorID FieldBase
---@field DeviceID FieldBase
---@field SubVendorID FieldBase
---@field SubDeviceID FieldBase
---@field Position FieldBase
---@field Manufacturer FieldBase
---@field LaneOwner FieldBase
---@field FirmwareVersion FieldBase
---@field PartNumber FieldBase
---@field Health FieldBase
---@field SerialNumber FieldBase
---@field LinkWidthAbility FieldBase
---@field LinkWidth FieldBase
---@field LinkSpeedCapability FieldBase
---@field LinkSpeed FieldBase
---@field RefComponent FieldBase
---@field NodeID FieldBase
---@field Presence FieldBase
---@field CardModel FieldBase
---@field CardManufacturer FieldBase
---@field CardForServers FieldBase
---@field HeartBeatLoss FieldBase
---@field CPUTemperatureCelsius FieldBase
---@field SFP1TemperatureCelsius FieldBase
---@field SFP2TemperatureCelsius FieldBase
---@field Inlet1TemperatureCelsius FieldBase
---@field Outlet1TemperatureCelsius FieldBase
---@field PowerWatts FieldBase
---@field NetworkAdapterChipTemperatureCelsius FieldBase
---@field Architecture FieldBase
---@field TotalCores FieldBase
---@field BIOSVersion FieldBase
---@field BiosBootStage FieldBase
---@field MemorySizeGiB FieldBase
---@field DiskCapacityGiB FieldBase
---@field SecureBootOptionEnabled FieldBase
---@field AssetType FieldBase
---@field AssetName FieldBase
---@field InventorySerialNumber FieldBase
---@field InventoryFirmwareVersion FieldBase
---@field InventoryPCBVersion FieldBase
---@field InventoryManufacturer FieldBase
---@field AssetTag FieldBase
---@field InventoryPartNumber FieldBase
---@field ManufactureDate FieldBase
---@field Slot FieldBase
---@field InventoryUUID FieldBase
---@field InventoryModel FieldBase
---@field RefChip FieldBase
---@field LockChip FieldBase
---@field RefIdChip FieldBase
---@field RefWPChip FieldBase
---@field SerialRecordConnect FieldBase
---@field RefFrudata FieldBase
---@field IgnoreSerialCableAlarm FieldBase
---@field CPUBoardName FieldBase
---@field NICBoardName FieldBase

---@class FwUpdateCfgTableTable: Table
---@field Id FieldBase
---@field ComponentId FieldBase
---@field ComponentIdex FieldBase
---@field Uid FieldBase

---@class SystemInfoListTable: Table
---@field Id FieldBase
---@field SystemInfo FieldBase

---@class CustomizeSignTable: Table
---@field Id FieldBase
---@field StartSlot FieldBase
---@field StartSlotItems FieldBase
---@field ActiveCondition FieldBase

---@class General_hardwareDBDatabase
---@field db DataBase
---@field select fun(db:DataBase, table: any, ...): SelectStatement
---@field update fun(db:DataBase, table: any, ...): UpdateStatement
---@field insert fun(db:DataBase, table: any, ...): InsertStatement
---@field CpldValidating CpldValidatingTable
---@field SecurityModule SecurityModuleTable
---@field DPUCard DPUCardTable
---@field FwUpdateCfgTable FwUpdateCfgTableTable
---@field SystemInfoList SystemInfoListTable
---@field CustomizeSign CustomizeSignTable
local General_hardwareDBDatabase = {}
General_hardwareDBDatabase.__index = General_hardwareDBDatabase

function General_hardwareDBDatabase.new(path, datas)
    local db = Databases(path)
    local obj = {db = db}

    obj.CpldValidating = db:Table('t_cpld_validating', {
        SystemId = Col.IntegerField():cid(1):primary_key():persistence_key('protect_reset'):max_length(8):default(1),
        ValidatingCpldFlag = Col.IntegerField():cid(2):persistence_key('protect_reset'):null():max_length(8):default(0)
    }):create_if_not_exist(datas and datas['t_cpld_validating'])
    obj.SecurityModule = db:Table('t_hardware_security_module', {
        Presence = Col.IntegerField():cid(1):null():max_length(8),
        Health = Col.IntegerField():cid(2):persistence_key('protect_power_off'):null():max_length(8):default(255),
        Protocol = Col.TextField():cid(3):persistence_key('protect_power_off'):null():default('\'TPM/TCM\''),
        Manufacturer = Col.TextField():cid(4):persistence_key('protect_power_off'):null():default('\'N/A\''),
        ProtocolVersion = Col.TextField():cid(5):persistence_key('protect_power_off'):null():default('\'N/A\''),
        FirmwareVersion = Col.TextField():cid(6):persistence_key('protect_power_off'):null():default('\'N/A\''),
        Id = Col.IntegerField():cid(7):primary_key():persistence_key('protect_power_off'):max_length(8)
    }):create_if_not_exist(datas and datas['t_hardware_security_module'])
    obj.DPUCard = db:Table('t_dpucard', {
        BootSourceOverrideMode = Col.IntegerField():cid(1):null():max_length(8):default(255),
        PxeOption = Col.TextField():cid(2):null():default('\'UefiIpv4\''),
        UUID = Col.TextField():cid(3):null(),
        BootSourceOverrideEnabled = Col.IntegerField():cid(4):null():max_length(8):default(255),
        M2SlotMaxCount = Col.IntegerField():cid(5):null():max_length(8),
        NetworkAdapterMaxCount = Col.IntegerField():cid(6):null():max_length(8),
        Model = Col.TextField():cid(7):null(),
        SystemLoadedStatus = Col.EnumField(DPUCard.SystemBootStatus):cid(8):persistence_key('protect_reset'):null(),
        SRVersion = Col.TextField():cid(9):null(),
        UID = Col.TextField():cid(10):null(),
        MRCLogLevel = Col.IntegerField():cid(11):persistence_key('protect_reset'):null():max_length(8),
        UEFILogLevel = Col.IntegerField():cid(12):persistence_key('protect_reset'):null():max_length(8),
        LogicVersion = Col.TextField():cid(13):null(),
        MultiLogicVersion = Col.JsonField():cid(14):null(),
        CPLDCount = Col.IntegerField():cid(15):null():max_length(8):default(1),
        PowerState = Col.TextField():cid(16):persistence_key('protect_reset'):null():default('\'Off\''),
        MPUBusyStatus = Col.IntegerField():cid(17):null():max_length(8),
        VrdVersion = Col.TextField():cid(18):null(),
        OSSupported = Col.BooleandField():cid(19):null():default(true),
        StorageIpAddr = Col.TextField():cid(20):null(),
        StorageIpVlan = Col.IntegerField():cid(21):null():max_length(16),
        M2SlotPresence = Col.IntegerField():cid(22):null():max_length(8),
        NetworkAdapterPresence = Col.IntegerField():cid(23):null():max_length(8),
        MCUVersion = Col.TextField():cid(24):null(),
        PfMacInfo = Col.JsonField():cid(25):null(),
        Name = Col.TextField():cid(26):null(),
        SlotID = Col.IntegerField():cid(27):primary_key():max_length(8),
        PCIeModel = Col.TextField():cid(28):null(),
        DeviceName = Col.TextField():cid(29):null(),
        FunctionClass = Col.IntegerField():cid(30):null():max_length(8),
        Description = Col.TextField():cid(31):null(),
        PcbVersion = Col.TextField():cid(32):null(),
        BoardID = Col.IntegerField():cid(33):null():max_length(16),
        BoardName = Col.TextField():cid(34):null(),
        VendorID = Col.IntegerField():cid(35):null():max_length(16),
        DeviceID = Col.IntegerField():cid(36):null():max_length(16),
        SubVendorID = Col.IntegerField():cid(37):null():max_length(16),
        SubDeviceID = Col.IntegerField():cid(38):null():max_length(16),
        Position = Col.TextField():cid(39):null(),
        Manufacturer = Col.TextField():cid(40):null(),
        LaneOwner = Col.IntegerField():cid(41):null():max_length(8),
        FirmwareVersion = Col.TextField():cid(42):null(),
        PartNumber = Col.TextField():cid(43):null(),
        Health = Col.IntegerField():cid(44):null():max_length(8),
        SerialNumber = Col.TextField():cid(45):null(),
        LinkWidthAbility = Col.TextField():cid(46):null(),
        LinkWidth = Col.TextField():cid(47):null(),
        LinkSpeedCapability = Col.TextField():cid(48):null(),
        LinkSpeed = Col.TextField():cid(49):null(),
        RefComponent = Col.TextField():cid(50):null(),
        NodeID = Col.TextField():cid(51):null(),
        Presence = Col.IntegerField():cid(52):null():max_length(8),
        CardModel = Col.TextField():cid(53):null(),
        CardManufacturer = Col.TextField():cid(54):null(),
        CardForServers = Col.JsonField():cid(55):null(),
        HeartBeatLoss = Col.IntegerField():cid(56):null():max_length(8),
        CPUTemperatureCelsius = Col.IntegerField():cid(57):null():max_length(16),
        SFP1TemperatureCelsius = Col.IntegerField():cid(58):null():max_length(16),
        SFP2TemperatureCelsius = Col.IntegerField():cid(59):null():max_length(16),
        Inlet1TemperatureCelsius = Col.IntegerField():cid(60):null():max_length(16),
        Outlet1TemperatureCelsius = Col.IntegerField():cid(61):null():max_length(16),
        PowerWatts = Col.IntegerField():cid(62):null():max_length(16),
        NetworkAdapterChipTemperatureCelsius = Col.IntegerField():cid(63):null():max_length(16),
        Architecture = Col.TextField():cid(64):null(),
        TotalCores = Col.IntegerField():cid(65):null():max_length(8),
        BIOSVersion = Col.TextField():cid(66):null(),
        BiosBootStage = Col.EnumField(System.BiosBootStatus):cid(67):persistence_key('protect_reset'):null(),
        MemorySizeGiB = Col.IntegerField():cid(68):null():max_length(16),
        DiskCapacityGiB = Col.IntegerField():cid(69):null():max_length(16),
        SecureBootOptionEnabled = Col.BooleandField():cid(70):null(),
        AssetType = Col.TextField():cid(71):null(),
        AssetName = Col.TextField():cid(72):null(),
        InventorySerialNumber = Col.TextField():cid(73):null(),
        InventoryFirmwareVersion = Col.TextField():cid(74):null(),
        InventoryPCBVersion = Col.TextField():cid(75):null(),
        InventoryManufacturer = Col.TextField():cid(76):null(),
        AssetTag = Col.TextField():cid(77):null(),
        InventoryPartNumber = Col.TextField():cid(78):null(),
        ManufactureDate = Col.TextField():cid(79):null(),
        Slot = Col.TextField():cid(80):null(),
        InventoryUUID = Col.TextField():cid(81):null(),
        InventoryModel = Col.TextField():cid(82):null(),
        RefChip = Col.JsonField():cid(83):null(),
        LockChip = Col.JsonField():cid(84):null(),
        RefIdChip = Col.JsonField():cid(85):null(),
        RefWPChip = Col.JsonField():cid(86):null(),
        SerialRecordConnect = Col.JsonField():cid(87):null(),
        RefFrudata = Col.JsonField():cid(88):null(),
        IgnoreSerialCableAlarm = Col.BooleandField():cid(89):null():default(false),
        CPUBoardName = Col.TextField():cid(90):null(),
        NICBoardName = Col.TextField():cid(91):null()
    }):create_if_not_exist(datas and datas['t_dpucard'])
    obj.FwUpdateCfgTable = db:Table('t_fw_cfg_info', {
        Id = Col.TextField():cid(1):primary_key(),
        ComponentId = Col.IntegerField():cid(2):primary_key():max_length(32),
        ComponentIdex = Col.IntegerField():cid(3):primary_key():max_length(32),
        Uid = Col.TextField():cid(4):null()
    }, 'protect_power_off'):create_if_not_exist(datas and datas['t_fw_cfg_info'])
    obj.SystemInfoList = db:Table('t_system_info_list', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        SystemInfo = Col.TextField():cid(2):persistence_key('protect_power_off'):null()
    }):create_if_not_exist(datas and datas['t_system_info_list'])
    obj.CustomizeSign = db:Table('t_customsize_sign', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        StartSlot = Col.BooleandField():cid(2):persistence_key('protect_power_off'):null():default(false),
        StartSlotItems = Col.JsonField():cid(3):persistence_key('protect_power_off'):null(),
        ActiveCondition = Col.TextField():cid(4):persistence_key('protect_power_off'):null():default('\'PowerOff\'')
    }):create_if_not_exist(datas and datas['t_customsize_sign'])

    obj.tables = db.tables
    return setmetatable(obj, General_hardwareDBDatabase)
end

function General_hardwareDBDatabase:select(table, ...)
    return self.db:select(table, ...)
end

function General_hardwareDBDatabase:update(table, ...)
    return self.db:update(table, ...)
end

function General_hardwareDBDatabase:insert(table, ...)
    return self.db:insert(table, ...)
end

function General_hardwareDBDatabase:delete(table, ...)
    return self.db:delete(table, ...)
end

function General_hardwareDBDatabase:exec(...)
    return self.db:exec(...)
end

return General_hardwareDBDatabase.new
