-- 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 class = require 'mc.class'
local package_cfg = require 'domain.bios_firmware.package.package_cfg'
local package = require 'domain.bios_firmware.package.package'
local log = require 'mc.logging'
local bios_enum = require 'domain.bios_firmware.defs'

local PackageBuilder = class()

local KUNPENGBEXID = 0x82
local TEEOSEXID = 0x83
local KRUNEXID = 0x84
local CCAEXID = 0x02000085

function PackageBuilder:ctor()
    -- 代次
    self.period = bios_enum.PackagePeriod.Period2
    -- 升级固件信息
    self.package_config = {}
end

local function get_period(firmware_idex)
    if firmware_idex == KUNPENGBEXID or firmware_idex == TEEOSEXID or
        firmware_idex == KRUNEXID or firmware_idex == CCAEXID then
        return bios_enum.PackagePeriod.Period3
    end
    return bios_enum.PackagePeriod.Period2
end

function PackageBuilder:set_period_by_firmware(firmware_info)
    if not firmware_info then
        self.period = bios_enum.PackagePeriod.Period2
        return self
    end
    self.period = get_period(firmware_info.idex)
    return self
end

function PackageBuilder:set_period_by_idex(firmware_idex)
    self.period = get_period(firmware_idex)
    return self
end

-- 基础包6.60(Version),补丁包6.60.HP001(Version)
function PackageBuilder:_update_package_type_period2()
    local cfg = self.package_config:get_cfg()
    local basic_version = cfg.basic.Version
    self.basic_version = basic_version
    local patch_version = string.match(basic_version, '(.+).HP.')
    if patch_version then
        self.package_type = bios_enum.PackageType.Patch
    else
        self.package_type = bios_enum.PackageType.Normal
    end
end

-- 基础包10.21(Version),补丁包10.21.HP001(Version+PatchVersion)
function PackageBuilder:_update_package_type_period3()
    local cfg = self.package_config:get_cfg()
    local basic_version = cfg.basic.Version
    local patch_version = cfg.basic.PatchVersion
    if patch_version and #patch_version > 0 then
        self.basic_version = string.format('%s.%s', basic_version, patch_version)
        self.package_type = bios_enum.PackageType.Patch
    else
        self.basic_version = basic_version
        self.package_type = bios_enum.PackageType.Normal
    end
    if self.idex == TEEOSEXID then
        self.package_type = bios_enum.PackageType.Tee
        log:notice('[bios]package builder: get teeos package')
    end

    if self.idex == KRUNEXID then
        self.package_type = bios_enum.PackageType.Krun
        log:notice('[bios]package builder: get krun package')
    end

    if self.idex == CCAEXID then
        self.package_type = bios_enum.PackageType.Cca
        log:notice('[bios]package builder: get Cca package')
    end
end

function PackageBuilder:_update_package_type()
    local package_type_fun = {
        [bios_enum.PackagePeriod.Period2] = PackageBuilder._update_package_type_period2,
        [bios_enum.PackagePeriod.Period3] = PackageBuilder._update_package_type_period3
    }
    local fun = package_type_fun[self.period]
    if fun then
        fun(self)
    end
end

function PackageBuilder:_update_period()
    local pack_cfg = self.package_config
    local cfgs = pack_cfg:get_cfg()
    if not cfgs or not cfgs.firmware_list or not cfgs.firmware_list[1] then
        log:error('[bios]package builder fail: firmware list is nil')
        error('firmware litst is nil')
    end
    self.period = get_period(cfgs.firmware_list[1].idex)
    self.idex = cfgs.firmware_list[1].idex
    self.uid_list = cfgs.firmware_list[1].uid_list or {}
end

function PackageBuilder:_set_update_cfg_path(path)
    self.package_config = package_cfg.new(path)
    self:_update_period()
end

function PackageBuilder:build(cfg_path)
    self:_set_update_cfg_path(cfg_path)
    self:_update_package_type()
    return package.new(self.package_config, self.package_type, self.period,
        self.basic_version, self.uid_list)
end

function PackageBuilder:build_with_snapshot(snapshot)
    return package.new({}, snapshot:get_package_type(), snapshot:get_period())
end

return PackageBuilder