-- 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 log = require 'mc.logging'
local vos = require 'utils.vos'
local utils = require 'mc.utils'
local utils_core = require 'utils.core'
local cjson = require 'cjson'

local m = {}

local TRIGGER_TYPE = {
    'caterror',
    'poweroff',
    'osreset'
}

local VIDEO_PATH = {
    '/data/share/video/video_caterror.rep',
    '/tmp/poweroff/video_poweroff.rep',
    '/tmp/osreset/video_osreset.rep'
}

local SYSTEM2_VIDEO_PATH = {
    '/data/share/video/system2_video_caterror.rep',
    '/tmp/poweroff/system2_video_poweroff.rep',
    '/tmp/osreset/system2_video_osreset.rep'
}

local VIDEO_FILE = {
    VIDEO_PATH,
    SYSTEM2_VIDEO_PATH
}

local SCREENSHOT_PATH = {
    Auto = {
        '/data/share/img/img1.jpeg',
        '/data/share/img/img2.jpeg',
        '/data/share/img/img3.jpeg'
    },
    Manual = {
        '/data/share/img/manualscreen.jpeg'
    }
}

local SYSTEM2_SCREENSHOT_PATH = {
    Auto = {
        '/data/share/img/system2_img1.jpeg',
        '/data/share/img/system2_img2.jpeg',
        '/data/share/img/system2_img3.jpeg'
    },
    Manual = {
        '/data/share/img/system2_manualscreen.jpeg'
    }
}

local SCREENSHOT_FILE = {
    SCREENSHOT_PATH,
    SYSTEM2_SCREENSHOT_PATH
}

local function get_file_attribute(file_path)
    local file_size = 0
    local create_time = cjson.null

    if vos.get_file_accessible(file_path) then
        local file_stat = utils_core.stat(file_path)
        file_size = file_stat.st_size
        create_time = utils.date_format(file_stat.st_mtim.tv_sec, "%Y-%m-%d %H:%M:%S", false)
    end
    return {file_size = file_size, create_time = create_time}
end

function m.get_video_attributes(system_ids)
    if not system_ids or #system_ids == 0 or system_ids == cjson.null then
        system_ids = {1}
    end
    local attributes = cjson.json_object_new_array()
    for _, system_id in ipairs(system_ids) do
        if not VIDEO_FILE[system_id] then
            goto continue
        end
        for index, file_path in ipairs(VIDEO_FILE[system_id]) do
            local temp_attr = get_file_attribute(file_path)
            if temp_attr.file_size == 0 then
                attributes[#attributes + 1] = cjson.null
            else
                local video_attribute = cjson.json_object_new_object()
                video_attribute.SystemId = system_id
                video_attribute.TriggerType = TRIGGER_TYPE[index]
                video_attribute.VideoSizeByte = temp_attr.file_size
                video_attribute.CreateTime = temp_attr.create_time
                attributes[#attributes + 1] = video_attribute
            end
        end
        ::continue::
    end
    return attributes
end

function m.get_screenshot_createtime(system_ids)
    if not system_ids or #system_ids == 0 or system_ids == cjson.null then
        system_ids = {1}
    end
    local create_time
    local attributes = cjson.json_object_new_array()
    for _, system_id in ipairs(system_ids) do
        if not SCREENSHOT_FILE[system_id] then
            goto continue
        end
        local screenshot_attribute = cjson.json_object_new_object()
        screenshot_attribute.SystemId = system_id
        local temp_create_time = cjson.json_object_new_object()
        for file_type, file_paths in pairs(SCREENSHOT_FILE[system_id]) do
            local tmp_array = cjson.json_object_new_array()
            for _, file_path in ipairs(file_paths) do
                create_time = get_file_attribute(file_path).create_time
                tmp_array[#tmp_array+1] = create_time ~= cjson.null and create_time or ""
            end
            temp_create_time[file_type] = tmp_array
        end
        screenshot_attribute.CreateTime = temp_create_time
        attributes[#attributes+1] = screenshot_attribute
        ::continue::
    end
    return attributes
end

function m.get_npu_path(npu_id)
    if not npu_id then
        return ''
    end
    local npu_list = mdb.get_sub_objects(bus, '/bmc/kepler/Systems/1/Processors/NPU',
        'bmc.kepler.Systems.Processor')
    for path, obj in pairs(npu_list) do
        if obj.Id == npu_id then
            return path
        end
    end
    return ''
end

local function get_npu_name(npu_obj_path)
    local ok, npu_obj = pcall(function ()
        return mdb.get_object(bus, npu_obj_path, 'bmc.kepler.Systems.Processor')
    end)
    if not ok then
        log:debug('Get npu obj failed, ret = %s', npu_obj)
        return nil
    end
    return npu_obj.Name
end

function m.get_npu_log_name(npu_obj_path)
    local npu_name = get_npu_name(npu_obj_path)
    if not npu_name then
        return
    end
    if string.match(npu_name, '(%d+)%-(%d+)') then
        return '/tmp/npu.tar.gz'
    end
    local log_name = '/tmp/' .. string.lower(npu_name) .. '_log.tar.gz'
    return log_name
end

function m.get_npu_device_log_name(npu_obj_path)
    local npu_name = get_npu_name(npu_obj_path)
    if not npu_name then
        return
    end
    if string.match(npu_name, '(%d+)%-(%d+)') then
        return '/tmp/npu_device_log.tar.gz'
    end
    local log_name = '/tmp/' .. string.lower(npu_name) .. '_device_log.tar.gz'
    return log_name
end

return m
