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

---@class BiosFwInfoTableTable: Table
---@field Id FieldBase
---@field Name FieldBase
---@field Version FieldBase
---@field BuildNum FieldBase
---@field ReleaseDate FieldBase
---@field LowestSupportedVersion FieldBase
---@field SoftwareId FieldBase
---@field Manufacturer FieldBase
---@field Updateable FieldBase
---@field Location FieldBase
---@field Capability FieldBase
---@field State FieldBase
---@field ActiveMode FieldBase
---@field ActiveModeSupported FieldBase
---@field ActiveModeEnabled FieldBase

---@class BiosBootOptionTableTable: Table
---@field Id FieldBase
---@field ValidFlag FieldBase
---@field SetInProgress FieldBase
---@field ServicePartitionSelector FieldBase
---@field ServicePartitionScan FieldBase
---@field BootFlagValidBitClearing FieldBase
---@field BootInfoAcknowledge FieldBase
---@field BootFlags FieldBase
---@field BootInitiatorInfo FieldBase
---@field BootInitiatorMailbox FieldBase
---@field WriteProtect FieldBase

---@class BiosBootTableTable: Table
---@field Id FieldBase
---@field BootModeSupport FieldBase
---@field BootModeIpmiSettable FieldBase
---@field BootSourceOverrideMode FieldBase
---@field BootSourceOverrideEnabled FieldBase
---@field BootSourceOverrideTarget FieldBase
---@field BootOrder FieldBase
---@field BootOptionPolicy FieldBase
---@field PreviousBootSourceOverrideTarget FieldBase

---@class BiosInfoTableTable: Table
---@field Id FieldBase
---@field Version FieldBase
---@field BackupVersion FieldBase
---@field OldSetupPassword FieldBase
---@field NewSetupPassword FieldBase
---@field UserOldSetupPassword FieldBase
---@field UserNewSetupPassword FieldBase
---@field UpgradeFailed FieldBase
---@field RecoverFailed FieldBase
---@field BiosLogPrintEnabled FieldBase
---@field RegistryVersion FieldBase
---@field SystemStartupState FieldBase
---@field BiosBootStage FieldBase
---@field TeeOSVersion FieldBase
---@field ResetBiosToDefaultsPending FieldBase

---@class BiosUpdateCfgTableTable: Table
---@field Id FieldBase
---@field idex FieldBase
---@field UpgradeFinishFlag FieldBase
---@field Version FieldBase
---@field EffectiveFlag FieldBase
---@field PackageType FieldBase
---@field Period FieldBase
---@field FirmwareEffectiveStatus FieldBase
---@field SlaveUpgrade FieldBase

---@class SmBiosInfoTableTable: Table
---@field Id FieldBase
---@field Version FieldBase
---@field SKUNumber FieldBase
---@field Family FieldBase
---@field SmBiosUpdatedFlag FieldBase
---@field SmBiosStatus FieldBase

---@class CertInfoTableTable: Table
---@field Id FieldBase
---@field CertificateExpired FieldBase

---@class BiosConfigTableTable: Table
---@field Id FieldBase
---@field FileChangeFlag FieldBase
---@field FileChannel FieldBase
---@field FileNum FieldBase

---@class CachedBiosUpgradeTableTable: Table
---@field Id FieldBase
---@field CachedBiosUpgradeMode FieldBase
---@field BiosActiveCondition FieldBase

---@class TeeOSFwInfoTableTable: Table
---@field Id FieldBase
---@field Name FieldBase
---@field Version FieldBase
---@field BuildNum FieldBase
---@field ReleaseDate FieldBase
---@field LowestSupportedVersion FieldBase
---@field SoftwareId FieldBase
---@field Manufacturer FieldBase
---@field Updateable FieldBase
---@field Location FieldBase
---@field Capability FieldBase
---@field State FieldBase
---@field ActiveMode FieldBase
---@field ActiveModeSupported FieldBase
---@field ActiveModeEnabled FieldBase

---@class AllowedBiosUpgradeTableTable: Table
---@field Id FieldBase
---@field PackageStatus FieldBase
---@field AllowedPackageType FieldBase

---@class BaseOSBootTable: Table
---@field SensorType FieldBase
---@field ReadingType FieldBase
---@field EventData FieldBase
---@field Id FieldBase

---@class BiosDBDatabase
---@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 BiosFwInfoTable BiosFwInfoTableTable
---@field BiosBootOptionTable BiosBootOptionTableTable
---@field BiosBootTable BiosBootTableTable
---@field BiosInfoTable BiosInfoTableTable
---@field BiosUpdateCfgTable BiosUpdateCfgTableTable
---@field SmBiosInfoTable SmBiosInfoTableTable
---@field CertInfoTable CertInfoTableTable
---@field BiosConfigTable BiosConfigTableTable
---@field CachedBiosUpgradeTable CachedBiosUpgradeTableTable
---@field TeeOSFwInfoTable TeeOSFwInfoTableTable
---@field AllowedBiosUpgradeTable AllowedBiosUpgradeTableTable
---@field BaseOSBoot BaseOSBootTable
local BiosDBDatabase = {}
BiosDBDatabase.__index = BiosDBDatabase

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

    obj.BiosFwInfoTable = db:Table('t_bios_fw_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        Name = Col.TextField():cid(2):persistence_key('protect_power_off'):null(),
        Version = Col.TextField():cid(3):persistence_key('protect_power_off'):null(),
        BuildNum = Col.TextField():cid(4):persistence_key('protect_power_off'):null(),
        ReleaseDate = Col.TextField():cid(5):persistence_key('protect_power_off'):null(),
        LowestSupportedVersion = Col.TextField():cid(6):persistence_key('protect_power_off'):null(),
        SoftwareId = Col.TextField():cid(7):persistence_key('protect_power_off'):null(),
        Manufacturer = Col.TextField():cid(8):persistence_key('protect_power_off'):null(),
        Updateable = Col.BooleandField():cid(9):persistence_key('protect_power_off'):null(),
        Location = Col.TextField():cid(10):persistence_key('protect_power_off'):null(),
        Capability = Col.IntegerField():cid(11):persistence_key('protect_power_off'):null():max_length(16),
        State = Col.TextField():cid(12):persistence_key('protect_power_off'):null(),
        ActiveMode = Col.TextField():cid(13):persistence_key('protect_power_off'):null(),
        ActiveModeSupported = Col.BooleandField():cid(14):persistence_key('protect_power_off'):null(),
        ActiveModeEnabled = Col.BooleandField():cid(15):persistence_key('protect_power_off'):null()
    }):create_if_not_exist(datas and datas['t_bios_fw_info'])
    obj.BiosBootOptionTable = db:Table('t_bios_boot_option_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        ValidFlag = Col.TextField():cid(2):persistence_key('protect_power_off'):null(),
        SetInProgress = Col.TextField():cid(3):persistence_key('protect_power_off'):null(),
        ServicePartitionSelector = Col.TextField():cid(4):persistence_key('protect_power_off'):null(),
        ServicePartitionScan = Col.TextField():cid(5):persistence_key('protect_power_off'):null(),
        BootFlagValidBitClearing = Col.TextField():cid(6):persistence_key('protect_power_off'):null(),
        BootInfoAcknowledge = Col.TextField():cid(7):persistence_key('protect_power_off'):null(),
        BootFlags = Col.TextField():cid(8):persistence_key('protect_power_off'):null(),
        BootInitiatorInfo = Col.TextField():cid(9):persistence_key('protect_power_off'):null(),
        BootInitiatorMailbox = Col.TextField():cid(10):persistence_key('protect_power_off'):null(),
        WriteProtect = Col.TextField():cid(11):persistence_key('protect_power_off'):null()
    }):create_if_not_exist(datas and datas['t_bios_boot_option_info'])
    obj.BiosBootTable = db:Table('t_bios_boot_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key(
            "protect_power_off"),
        BootModeSupport = Col.BooleandField():cid(2):persistence_key(
            "protect_power_off"):null(),
        BootModeIpmiSettable = Col.BooleandField():cid(3):persistence_key(
            "protect_power_off"):null(),
        BootSourceOverrideMode = Col.TextField():cid(4):persistence_key(
            "protect_power_off"):null(),
        BootSourceOverrideEnabled = Col.TextField():cid(5):persistence_key(
            "protect_power_off"):null(),
        BootSourceOverrideTarget = Col.TextField():cid(6):persistence_key(
            "protect_power_off"):null(),
        BootOrder = Col.TextField():cid(7):persistence_key("protect_power_off")
            :null(),
        BootOptionPolicy = Col.IntegerField():cid(8):null():max_length(8),
        PreviousBootSourceOverrideTarget = Col.TextField():cid(9)
            :persistence_key("protect_power_off"):null()
    }):create_if_not_exist(datas and datas['t_bios_boot_info'])
    obj.BiosInfoTable = db:Table('t_bios_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        Version = Col.TextField():cid(2):persistence_key('protect_power_off'):null(),
        BackupVersion = Col.TextField():cid(3):persistence_key('protect_power_off'):null(),
        OldSetupPassword = Col.TextField():cid(4):persistence_key('protect_power_off'):null(),
        NewSetupPassword = Col.TextField():cid(5):persistence_key('protect_power_off'):null(),
        UserOldSetupPassword = Col.TextField():cid(6):persistence_key('protect_power_off'):null(),
        UserNewSetupPassword = Col.TextField():cid(7):persistence_key('protect_power_off'):null(),
        UpgradeFailed = Col.IntegerField():cid(8):persistence_key('protect_power_off'):null():max_length(8),
        RecoverFailed = Col.IntegerField():cid(9):persistence_key('protect_power_off'):null():max_length(8),
        BiosLogPrintEnabled = Col.IntegerField():cid(10):persistence_key('protect_power_off'):null():max_length(8),
        RegistryVersion = Col.TextField():cid(11):persistence_key('protect_power_off'):null():default('\'V0.00\''),
        SystemStartupState = Col.IntegerField():cid(12):persistence_key('protect_reset'):null():max_length(8):default(0),
        BiosBootStage = Col.IntegerField():cid(13):persistence_key('protect_reset'):null():max_length(8):default(0),
        TeeOSVersion = Col.TextField():cid(14):persistence_key('protect_power_off'):null():default('\'\''),
        ResetBiosToDefaultsPending = Col.BooleandField():cid(15):persistence_key('protect_reset'):null():default(false)
    }):create_if_not_exist(datas and datas['t_bios_info'])
    obj.BiosUpdateCfgTable = db:Table('t_bios_cfg_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        idex = Col.IntegerField():cid(2):persistence_key('protect_power_off'):null():max_length(32),
        UpgradeFinishFlag = Col.BooleandField():cid(3):persistence_key('protect_power_off'):null():default(true),
        Version = Col.TextField():cid(4):persistence_key('protect_power_off'):null(),
        EffectiveFlag = Col.IntegerField():cid(5):persistence_key('protect_power_off'):null():max_length(32),
        PackageType = Col.IntegerField():cid(6):persistence_key('protect_power_off'):null():max_length(32),
        Period = Col.IntegerField():cid(7):persistence_key('protect_power_off'):null():max_length(32),
        FirmwareEffectiveStatus = Col.IntegerField():cid(8):persistence_key('protect_power_off'):null():max_length(8),
        SlaveUpgrade = Col.BooleandField():cid(9):persistence_key('protect_reset'):null():default(false)
    }):create_if_not_exist(datas and datas['t_bios_cfg_info'])
    obj.SmBiosInfoTable = db:Table('t_smbios_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        Version = Col.TextField():cid(2):persistence_key('protect_power_off'):null(),
        SKUNumber = Col.TextField():cid(3):persistence_key('protect_power_off'):null(),
        Family = Col.TextField():cid(4):persistence_key('protect_power_off'):null(),
        SmBiosUpdatedFlag = Col.IntegerField():cid(5):persistence_key('protect_reset'):null():max_length(8),
        SmBiosStatus = Col.IntegerField():cid(6):persistence_key('protect_reset'):null():max_length(8):default(4)
    }):create_if_not_exist(datas and datas['t_smbios_info'])
    obj.CertInfoTable = db:Table('t_cert_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        CertificateExpired = Col.IntegerField():cid(2):persistence_key('protect_power_off'):null():max_length(8)
            :default(0)
    }):create_if_not_exist(datas and datas['t_cert_info'])
    obj.BiosConfigTable = db:Table('t_bios_config_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'),
        FileChangeFlag = Col.IntegerField():cid(2):persistence_key('protect_power_off'):null():max_length(8):default(0),
        FileChannel = Col.IntegerField():cid(3):persistence_key('protect_power_off'):null():max_length(8):default(0),
        FileNum = Col.IntegerField():cid(4):persistence_key('protect_power_off'):null():max_length(8):default(0)
    }):create_if_not_exist(datas and datas['t_bios_config_info'])
    obj.CachedBiosUpgradeTable = db:Table('t_cached_bios_upgrade_info', {
        Id = Col.IntegerField():cid(1):primary_key():max_length(8),
        CachedBiosUpgradeMode = Col.IntegerField():cid(2):null():max_length(8):default(0),
        BiosActiveCondition = Col.TextField():cid(3):persistence_key('protect_power_off'):null():default('\'PowerOff\'')
    }, 'protect_reset'):create_if_not_exist(datas and datas['t_cached_bios_upgrade_info'])
    obj.TeeOSFwInfoTable = db:Table('t_teeos_fw_info', {
        Id = Col.TextField():cid(1):primary_key():persistence_key('protect_power_off'):default('\'TeeOS\''),
        Name = Col.TextField():cid(2):persistence_key('protect_power_off'):null():default('\'TeeOS\''),
        Version = Col.TextField():cid(3):persistence_key('protect_power_off'):null():default('\'0.00\''),
        BuildNum = Col.TextField():cid(4):persistence_key('protect_power_off'):null():default('\'\''),
        ReleaseDate = Col.TextField():cid(5):persistence_key('protect_power_off'):null():default('\'\''),
        LowestSupportedVersion = Col.TextField():cid(6):persistence_key('protect_power_off'):null():default('\'\''),
        SoftwareId = Col.TextField():cid(7):persistence_key('protect_power_off'):null():default('\'TeeOS-TeeOS\''),
        Manufacturer = Col.TextField():cid(8):persistence_key('protect_power_off'):null():default('\'Huawei\''),
        Updateable = Col.BooleandField():cid(9):persistence_key('protect_power_off'):null():default(true),
        Location = Col.TextField():cid(10):persistence_key('protect_power_off'):null():default('\'U75\''),
        Capability = Col.IntegerField():cid(11):persistence_key('protect_power_off'):null():max_length(16):default(5),
        State = Col.TextField():cid(12):persistence_key('protect_power_off'):null():default('\'Enabled\''),
        ActiveMode = Col.TextField():cid(13):persistence_key('protect_power_off'):null():default('\'\''),
        ActiveModeSupported = Col.BooleandField():cid(14):persistence_key('protect_power_off'):null():default(true),
        ActiveModeEnabled = Col.BooleandField():cid(15):persistence_key('protect_power_off'):null():default(true)
    }):create_if_not_exist(datas and datas['t_teeos_fw_info'])
    obj.AllowedBiosUpgradeTable = db:Table('t_allowed_bios_upgrade_info', {
        Id = Col.IntegerField():cid(1):primary_key():max_length(8):default(1),
        PackageStatus = Col.IntegerField():cid(2):null():max_length(8):default(0),
        AllowedPackageType = Col.IntegerField():cid(3):null():max_length(8)
    }, 'protect_power_off'):create_if_not_exist(datas and datas['t_allowed_bios_upgrade_info'])
    obj.BaseOSBoot = db:Table('t_base_os_boot', {
        SensorType = Col.IntegerField():cid(1):null():max_length(8):default(31),
        ReadingType = Col.IntegerField():cid(2):persistence_key('protect_reset'):null():max_length(8):default(111),
        EventData = Col.IntegerField():cid(3):persistence_key('protect_reset'):null():max_length(32):default(4294967295),
        Id = Col.IntegerField():cid(4):primary_key():max_length(8):default(1)
    }):create_if_not_exist(datas and datas['t_base_os_boot'])

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

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

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

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

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

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

return BiosDBDatabase.new
