-- Copyright (c) 2026 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 db_selector = {}

---@class PCIeVPDInfoTable: Table
---@field DevBus FieldBase
---@field DevDevice FieldBase
---@field DevFunction FieldBase
---@field SerialNumber FieldBase
---@field PartNumber FieldBase

---@class PCIeLoadInfoBackupTable: Table
---@field Type FieldBase
---@field SlotID FieldBase
---@field ID FieldBase
---@field AuxID FieldBase
---@field Segment FieldBase
---@field SocketID FieldBase
---@field DevBus FieldBase
---@field DevDevice FieldBase
---@field DevFunction FieldBase
---@field MultihostPresence FieldBase
---@field RecoverFlag FieldBase

---@class PCIeFunctionLoadInfoTable: Table
---@field DeviceType FieldBase
---@field SlotId FieldBase
---@field SegmentNumber FieldBase
---@field BusNumber FieldBase
---@field DeviceNumber FieldBase
---@field FunctionNumber FieldBase
---@field LogicProcessorId FieldBase
---@field SystemId FieldBase

---@class SystemsPCIeTopoInfoTable: Table
---@field GlobalSystemId FieldBase
---@field LocalSystemId FieldBase
---@field Segment FieldBase
---@field Socket FieldBase
---@field Bus FieldBase
---@field Device FieldBase
---@field Function FieldBase
---@field GroupId FieldBase
---@field ComponentType FieldBase
---@field Slot FieldBase
---@field VendorId FieldBase
---@field DeviceId FieldBase
---@field SecBus FieldBase
---@field SubBus FieldBase
---@field BDFNo FieldBase
---@field Reserved1 FieldBase
---@field CfgLowBase FieldBase
---@field CfgLowLimit FieldBase
---@field CfgHighBase FieldBase
---@field CfgHighLimit FieldBase
---@field Reserved2 FieldBase
---@field Reserved4 FieldBase
---@field UpdateFlag FieldBase
---@field MMIOCnt FieldBase
---@field MMIO0Base FieldBase
---@field MMIO0Limit FieldBase
---@field MMIO1Base FieldBase
---@field MMIO1Limit FieldBase
---@field MMIO2Base FieldBase
---@field MMIO2Limit FieldBase
---@field MMIO3Base FieldBase
---@field MMIO3Limit FieldBase
---@field MMIO4Base FieldBase
---@field MMIO4Limit FieldBase
---@field MMIO5Base FieldBase
---@field MMIO5Limit FieldBase

---@class Pcie_deviceDBDatabaseReset
---@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 PCIeVPDInfo PCIeVPDInfoTable
---@field PCIeLoadInfoBackup PCIeLoadInfoBackupTable
---@field PCIeFunctionLoadInfo PCIeFunctionLoadInfoTable
---@field SystemsPCIeTopoInfo SystemsPCIeTopoInfoTable

local Pcie_deviceDBDatabaseReset = {}
Pcie_deviceDBDatabaseReset.__index = Pcie_deviceDBDatabaseReset

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

    obj.PCIeVPDInfo = db:Table('t_pcie_vpd_info', {
        DevBus = Col.IntegerField():cid(1):primary_key():max_length(8),
        DevDevice = Col.IntegerField():cid(2):primary_key():max_length(8),
        DevFunction = Col.IntegerField():cid(3):primary_key():max_length(8),
        SerialNumber = Col.TextField():cid(4):null(),
        PartNumber = Col.TextField():cid(5):null()
    }):create_if_not_exist(datas and datas['t_pcie_vpd_info'])
    obj.PCIeLoadInfoBackup = db:Table('t_pcie_load_info_backup', {
        Type = Col.TextField():cid(1):primary_key():default('\'NA\''),
        SlotID = Col.IntegerField():cid(2):primary_key():max_length(8):default(0),
        ID = Col.IntegerField():cid(3):null():max_length(32):default(0),
        AuxID = Col.IntegerField():cid(4):null():max_length(32):default(0),
        Segment = Col.IntegerField():cid(5):null():max_length(8):default(0),
        SocketID = Col.IntegerField():cid(6):null():max_length(8):default(0),
        DevBus = Col.IntegerField():cid(7):null():max_length(8):default(0),
        DevDevice = Col.IntegerField():cid(8):null():max_length(8):default(0),
        DevFunction = Col.IntegerField():cid(9):null():max_length(8):default(0),
        MultihostPresence = Col.IntegerField():cid(10):null():max_length(32):default(1),
        RecoverFlag = Col.IntegerField():cid(11):null():max_length(8):default(0)
    }):create_if_not_exist(datas and datas['t_pcie_load_info_backup'])
    obj.PCIeFunctionLoadInfo = db:Table('t_pcie_function_load_info', {
        DeviceType = Col.TextField():cid(1):primary_key():default('\'N/A\''),
        SlotId = Col.IntegerField():cid(2):primary_key():max_length(8):default(0),
        SegmentNumber = Col.IntegerField():cid(3):primary_key():max_length(16):default(65535),
        BusNumber = Col.IntegerField():cid(4):primary_key():max_length(8):default(255),
        DeviceNumber = Col.IntegerField():cid(5):primary_key():max_length(8):default(255),
        FunctionNumber = Col.IntegerField():cid(6):primary_key():max_length(8):default(255),
        LogicProcessorId = Col.IntegerField():cid(7):null():max_length(8):default(255),
        SystemId = Col.IntegerField():cid(8):null():max_length(8):default(255)
    }):create_if_not_exist(datas and datas['t_pcie_function_load_info'])
    obj.SystemsPCIeTopoInfo = db:Table('t_systems_pcie_topo_info', {
        GlobalSystemId = Col.IntegerField():cid(1):primary_key():max_length(8):default(0),
        LocalSystemId = Col.IntegerField():cid(2):primary_key():max_length(8):default(0),
        Segment = Col.IntegerField():cid(3):primary_key():max_length(8):default(0),
        Socket = Col.IntegerField():cid(4):primary_key():max_length(8):default(0),
        Bus = Col.IntegerField():cid(5):primary_key():max_length(8):default(0),
        Device = Col.IntegerField():cid(6):primary_key():max_length(8):default(0),
        Function = Col.IntegerField():cid(7):primary_key():max_length(8):default(0),
        GroupId = Col.IntegerField():cid(8):null():max_length(8):default(0),
        ComponentType = Col.IntegerField():cid(9):null():max_length(8):default(0),
        Slot = Col.IntegerField():cid(10):null():max_length(8):default(0),
        VendorId = Col.IntegerField():cid(11):null():max_length(16):default(0),
        DeviceId = Col.IntegerField():cid(12):null():max_length(16):default(0),
        SecBus = Col.IntegerField():cid(13):null():max_length(8):default(0),
        SubBus = Col.IntegerField():cid(14):null():max_length(8):default(0),
        BDFNo = Col.IntegerField():cid(15):null():max_length(8):default(0),
        Reserved1 = Col.IntegerField():cid(16):null():max_length(8):default(0),
        CfgLowBase = Col.IntegerField():cid(17):null():max_length(32):default(0),
        CfgLowLimit = Col.IntegerField():cid(18):null():max_length(32):default(0),
        CfgHighBase = Col.IntegerField():cid(19):null():max_length(64):default(0),
        CfgHighLimit = Col.IntegerField():cid(20):null():max_length(64):default(0),
        Reserved2 = Col.IntegerField():cid(21):null():max_length(16):default(0),
        Reserved4 = Col.IntegerField():cid(22):null():max_length(32):default(0),
        UpdateFlag = Col.IntegerField():cid(23):null():max_length(8):default(0),
        MMIOCnt = Col.IntegerField():cid(24):null():max_length(8):default(0),
        MMIO0Base = Col.IntegerField():cid(25):null():max_length(64):default(0),
        MMIO0Limit = Col.IntegerField():cid(26):null():max_length(64):default(0),
        MMIO1Base = Col.IntegerField():cid(27):null():max_length(64):default(0),
        MMIO1Limit = Col.IntegerField():cid(28):null():max_length(64):default(0),
        MMIO2Base = Col.IntegerField():cid(29):null():max_length(64):default(0),
        MMIO2Limit = Col.IntegerField():cid(30):null():max_length(64):default(0),
        MMIO3Base = Col.IntegerField():cid(31):null():max_length(64):default(0),
        MMIO3Limit = Col.IntegerField():cid(32):null():max_length(64):default(0),
        MMIO4Base = Col.IntegerField():cid(33):null():max_length(64):default(0),
        MMIO4Limit = Col.IntegerField():cid(34):null():max_length(64):default(0),
        MMIO5Base = Col.IntegerField():cid(35):null():max_length(64):default(0),
        MMIO5Limit = Col.IntegerField():cid(36):null():max_length(64):default(0)
    }):create_if_not_exist(datas and datas['t_systems_pcie_topo_info'])

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

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

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

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

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

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

db_selector['reset'] = Pcie_deviceDBDatabaseReset.new

local Pcie_deviceDBDatabase = {}
Pcie_deviceDBDatabase.__index = Pcie_deviceDBDatabase

function Pcie_deviceDBDatabase.new(path, datas, type)
    return db_selector[type] and db_selector[type](path, datas) or nil
end

return Pcie_deviceDBDatabase.new
