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

-- Description: 通用任务处理

local skynet = require 'skynet'
local log = require 'mc.logging'
local task_mgmt = require 'mc.mdb.task_mgmt'

local create_task_err_code<const> = task_mgmt.create_code
local update_task_err_code<const> = task_mgmt.update_code

local task = {}

-- 销毁任务
function task.destroy_task_by_id(task_id)
    if not task[task_id] then
        return
    end
    log:notice('destroy_task_by_id: %d', task_id)
    local ok, err = pcall(task_mgmt.destroy_task, task_id)
    if not ok then
        log:error('call task_mgmt.destroy_task failed, err(%s)', err)
    end
    task[task_id] = nil
end

-- 创建任务
function task.create(bus, task_name, path)
    local res, task_err, task_id = task_mgmt.create_task(bus, task_name, path)
    if res ~= create_task_err_code.TASK_CREATE_SUCCESSFUL then
        log:error('Create task failed, res: %d', res)
        return nil, task_err
    end

    task[task_id] = { obj = task_mgmt.get_task_obj(task_id) }
    log:notice('task create success, task id: %d', task_id)

    -- 在5分钟后释放表空间
    skynet.timeout(5 * 60 * 100, function()
        task.destroy_task_by_id(task_id)
    end)

    return task_id
end

local function destroy_dup_task(new_task_id, info_key)
    for task_id, _ in pairs(task) do
        if type(task_id) == type(new_task_id) and task_id ~= new_task_id then
            if task[task_id].info_key == info_key then
                log:notice('destroy_dup_task: task(%s) dup, task id: %d -> %d', info_key, task_id, new_task_id)
                task.destroy_task_by_id(task_id)
            end
        end
    end
end

function task.init(task_id, info_key)
    if not task[task_id] then
        log:error('task init sequence error, %s task id: %d', info_key, task_id)
        task[task_id] = {}
    end
    task[task_id].info_key = info_key
    -- 删除重复的任务资源信息
    destroy_dup_task(task_id, info_key)
end

-- 更新任务状态，如果某属性不需要更新（保持当前值），直接传nil
function task.update(task_id, task_data)
    local res = task_mgmt.update_task(task_id, task_data)
    if res ~= update_task_err_code.TASK_UPDATE_SUCCESSFUL then
        log:error('Update task failed, task_id: %s, res: %d', task_id, res)
    end
end

-- 更新state/status和message_id
function task.update_easy(task_id, task_state, task_status, message_id, message_args)
    local task_data = {
        State = tostring(task_state),
        Status = tostring(task_status)
    }
    if message_id then
        task_data.MessageId = message_id
    end
    if message_args then
        task_data.MessageArgs = message_args
    end
    task.update(task_id, task_data)
end

function task.get_task_status(task_id)
    if task[task_id] == nil then
        return nil
    end

    return task[task_id].obj and task[task_id].obj.Status
end

return task
