-- 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 task_mgmt = require 'mc.mdb.task_mgmt'
local NVME_MI_OPTIONS = require 'nvme.nvme_mi_protocol.nvme_mi_def'

local m = {}

-- 解析从芯片中读取的二进制字符串
function m.string_split(str, seq, numeration)
    if not str then
        return
    end

    local a = {}
    for word in string.gmatch(str, '[^{' .. seq .. '}*]+') do
        table.insert(a, tonumber(word, numeration))
    end

    return a
end

-- 将二进制字符串取反
function m.negation(number, length)
    local bit_arr = {}
    for i = length - 1, 0, -1 do
        table.insert(bit_arr, math.floor(number / 2^i))
        number = number % 2^i
    end

    for k, v in pairs(bit_arr) do
        bit_arr[k] = v == 0 and 1 or 0
    end

    return tonumber(table.concat(bit_arr), 2)
end

-- 解析nvme mi协议响应码
function m.parse_rsp_status(bin)
    local rsp = NVME_MI_OPTIONS.responss_message:unpack(bin, true)
    if not rsp then
        log:debug('empty data received for nvme-mi response')
        return
    end
    local status = rsp.status
    if (not status) or (status ~= 0 and status ~= 1) then
        local rsp_ststus_str = NVME_MI_OPTIONS.response_status[status] or 'other error response'
        log:debug('status values that indicate an error: %s %s', rsp.status, rsp_ststus_str)
        return
    end
    return rsp.data
end

-- 按低字节在表头返回表格
function m.little_endian_table(data)
    local tab = {}
    for i = #data, 1, -1 do
        table.insert(tab, data:byte(i))
    end
    return tab
end

-- 低字节在表头,反转返回字符串
function m.little_endian_str(data)
    local str = ''
    for i = #data, 1, -1 do
        str = str .. string.char(data[i])
    end
    return str
end

-- 更新任务状态
function m.update_task(task_id, progress, state, status)
    local data = {
        Progress = progress,
        State = state,
        Status = status
    }
    local updata = task_mgmt.update_task(task_id, data)
    if updata ~= task_mgmt.update_code.TASK_UPDATE_SUCCESSFUL then
        log:info('update task failed')
    end
end

-- 校验字符串是否包含不可见字符（排除空格）
function m.has_invisible_chars(str)
    if not str or type(str) ~= "string" then
        return false
    end
    -- 匹配不可见字符（排除空格）
    return string.find(str, "%c") ~= nil
end

return m
