-- 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 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 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

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.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
