-- 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 file_op = require 'service.file.file_operation'
local prop_global = require 'macros.property_global'
local log = require 'mc.logging'
local bios_enum = require 'bios.types.enums'
local bs_util = require 'util.base_util'
local json_util = require 'util.json_util'
local json = require 'cjson'
local prop_def = require 'macros.property_def'
local utils_core = require 'utils.core'
local utils = require 'mc.utils'
local bios_factory = require 'factory.bios_factory'

local OperationImpl = {}

-- 以下为写文件时的操作
local TOperationMenuData = class(file_op)
function TOperationMenuData.write_data(bios_obj, file_selector, data_opt)
end

OperationImpl.OperationMenuData = TOperationMenuData

local TOperationClp = class(file_op)
function TOperationClp.write_data(bios_obj, file_selector, data_opt)
end

OperationImpl.OperationClp = TOperationClp

local TOperationSecureBoot = class(file_op)
function TOperationSecureBoot.write_data(bios_obj, file_selector, data_opt)
    log:notice('[bios] write file: start write current secureboot file.')
    local current_path = bios_obj:get_prop('SecureBootCurrentFile')
    local new_path = bios_obj:get_prop('SecureBootNewFile')
    bs_util.clear_file(current_path)
    bs_util.write_file_data(current_path, data_opt:get_buf())
    bs_util.clear_file(new_path)
    utils_core.chmod_s(current_path, utils.S_IRUSR | utils.S_IWUSR) -- 修改权限为600
    utils_core.chmod_s(new_path, utils.S_IRUSR | utils.S_IWUSR) -- 修改权限为600
    local secure_boot_options_ser = bios_factory.get_service('secure_boot_options_service')
    if not secure_boot_options_ser then
        log:error('secure_boot_options_service is nil')
    else
        local sec_options_obj = secure_boot_options_ser:get_obj(bios_obj.system_id)
        if sec_options_obj then
            sec_options_obj:update_cer_info_db(json.encode(bs_util.create_default_cer_json()))
        end
    end
    return bios_enum.BiosErrCode.BIOS_ERR_NORMALLY:value()
end

OperationImpl.OperationSecureBoot = TOperationSecureBoot

local TOperationFile = class(file_op)
function TOperationFile.write_data(bios_obj, file_selector, data_opt)
    local len = #prop_global.G_FILE_PROPERTY_NAME
    local real_file_selector = file_selector + 1
    if real_file_selector > len then
        log:error("write_file_finish: file_selector(%u) is out of range", file_selector)
        return bios_enum.BiosErrCode.BIOS_ERR_IV_LEN:value()
    end

    local file_prop = prop_global.G_FILE_PROPERTY_NAME[real_file_selector]
    local file_name = bios_obj:get_prop(file_prop)
    if not file_name then
        log:error("write_file_finish: file_selector(%u) get fileName fail", file_selector)
        return bios_enum.BiosErrCode.BIOS_ERR_INVALID_STATUS:value()
    end

    local ok, file_json_data = pcall(json.json_object_ordered_decode, data_opt:get_buf())
    if not ok then
        log:error('write_file_finish decode json data fail')
        return bios_enum.BiosErrCode.BIOS_ERR_FM_FAIL:value()
    end
    local result = json_util.write_file_data(file_json_data, file_name)
    if result ~= prop_def.E_OK then
        log:error("write_file_finish OperationFile %s write fail!", file_selector)
        return bios_enum.BiosErrCode.BIOS_ERR_FM_FAIL:value()
    end

    log:notice("write_file_finish OperationFile write file len(%d)!", #data_opt:get_buf())

    return bios_enum.BiosErrCode.BIOS_ERR_NORMALLY:value()
end

OperationImpl.OperationFile = TOperationFile

return OperationImpl