-- 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 skynet = require 'skynet'
local ncsi_cmd = require 'ncsi.ncsi_protocol.ncsi_cmd'

local ncsi_core = {}

local NCSI_FALSE = 1
local NCSI_TRUE = 0

pcall(function()
    skynet.register_protocol({
        name = 'network_adapter_ncsi_reinit',
        id = 132, -- 此id仅本模块使用，不重复即可
        pack = skynet.pack,
        unpack = skynet.unpack
    })
end)

-- ncsi cmd
function ncsi_core.ncsi_clear_initial_state(package_id, channel_id, eth_name)
    log:notice('ncsi: Clear initial state. package_id=%d, channel_d=%d, eth_name=%s', package_id,
        channel_id, eth_name)
    local ret = ncsi_cmd.ncsi_clear_initial_state(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Clear initial state failed.')
        return false
    end
    return true
end

function ncsi_core.ncsi_select_package(package_id, eth_name)
    log:notice('ncsi: Select Package. package_id=%d, eth_name=%s', package_id, eth_name)
    local ret = ncsi_cmd.ncsi_select_package(package_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Select Package failed.')
        return false
    end
    return true
end
function ncsi_core.ncsi_disable_channel(package_id, channel_id, eth_name)
    log:notice('ncsi: Disable channel. package_id=%d, channel_d=%d, eth_name=%s', package_id,
        channel_id, eth_name)
    local ret = ncsi_cmd.ncsi_disable_channel(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Disable channel failed.')
        return false
    end
    return true
end
function ncsi_core.ncsi_enable_channel(package_id, channel_id, eth_name)
    log:notice('ncsi: Enable channel. package_id=%d, channel_d=%d, eth_name=%s', package_id,
        channel_id, eth_name)
    local ret = ncsi_cmd.ncsi_enable_channel(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Enable channel failed.', package_id, channel_id, eth_name)
        return false
    end
    return true
end
function ncsi_core.ncsi_enable_brdcast_filter(package_id, channel_id, eth_name)
    log:notice('ncsi: Enable broadcast filter. package_id=%d, channel_d=%d, eth_name=%s',
        package_id, channel_id, eth_name)
    local ret = ncsi_cmd.ncsi_enable_brdcast_filter(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Enable broadcast filter failed.')
        return false
    end
    return true
end
function ncsi_core.ncsi_disable_brdcast_filter(package_id, channel_id, eth_name)
    log:notice('ncsi: Disable broadcast filter. package_id=%d, channel_d=%d, eth_name=%s',
        package_id, channel_id, eth_name)
    local ret = ncsi_cmd.ncsi_disable_brdcast_filter(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Disable broadcast filter failed.')
        return false
    end
    return true
end
function ncsi_core.ncsi_disable_multi_filter(package_id, channel_id, eth_name)
    log:notice('ncsi: Disable multicast filter. package_id=%d, channel_d=%d, eth_name=%s',
        package_id, channel_id, eth_name)
    local ret = ncsi_cmd.ncsi_disable_multi_filter(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Disable multicast filter failed.')
        return false
    end
    return true
end
function ncsi_core.ncsi_enable_multi_filter(package_id, channel_id, eth_name)
    log:notice('ncsi: Enable multicast filter. package_id=%d, channel_d=%d, eth_name=%s',
        package_id, channel_id, eth_name)
    local ret = ncsi_cmd.ncsi_enable_multi_filter(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Enable multicast filter failed.')
        return false
    end
    return true
end
function ncsi_core.ncsi_enable_channelTX(package_id, channel_id, eth_name)
    log:info('ncsi: Enable channel TX. package_id = %d, channel_d = %d, eth_name = %s',
        package_id, channel_id, eth_name)
    local ret = ncsi_cmd.ncsi_enable_channelTX(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Enable channel TX failed.')
        return false
    end
    return true
end
function ncsi_core.ncsi_disable_channelTX(package_id, channel_id, eth_name)
    log:notice('ncsi: Disable channel TX. package_id = %d, channel_d = %d, eth_name = %s',
        package_id, channel_id, eth_name)
    local ret = ncsi_cmd.ncsi_disable_channelTX(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Disable channel TX failed.')
        return false
    end
    return true
end
function ncsi_core.ncsi_set_vlan_filter(package_id, channel_id, vlan_filter, vlan_state, vlan_id,
    eth_name)
    log:notice(
        'ncsi:Set vlan filter. package_id=%d, channel_d=%d, eth_name=%s, vlan_id=%d, vlan_state=%d, vlan_filter=%d',
        package_id, channel_id, eth_name, vlan_id, vlan_state, vlan_filter)
    local ret = ncsi_cmd.ncsi_set_vlan_filter(package_id, channel_id, vlan_filter, vlan_state, vlan_id, eth_name)
    if ret == NCSI_FALSE then
        log:error('ncsi: Set vlan filter failed.')
        return false
    end
    return true
end
function ncsi_core.ncsi_get_link_status(package_id, channel_id, eth_name, eth_id)
    local l_ret = true
    local ret, link_status = ncsi_cmd.ncsi_get_link_status(package_id, channel_id, eth_name, eth_id)
    if ret == NCSI_FALSE then
        l_ret = false
    end
    return l_ret, link_status
end

-- ncsi oem
function ncsi_core.ncsi_common_init()
    ncsi_cmd.ncsi_common_init()
end

function ncsi_core.ncsi_paramter_init(channel_id, eth_name, state)
    local l_ret = true

    log:info('ncsi: Paramter init. channel_id=%d, eth_name=%s, state=%d', channel_id, eth_name,
        state)
    local ret, package_id = ncsi_cmd.ncsi_paramter_init(channel_id, eth_name, state)
    if ret == NCSI_FALSE then
        log:error('ncsi: Paramter init failed.')
        l_ret = false
    end
    return l_ret, package_id
end

function ncsi_core.ncsi_receive_packet(fd, eth_name)
    local ret, aen_oem_status, data = ncsi_cmd.ncsi_receive_packet(fd, eth_name)
    if ret ~= NCSI_TRUE then
        return
    end
    -- 收到网卡的aen oem报文后，给上层发送信号，重新下发ncsi配置
    if aen_oem_status == 1 then
        log:notice('aen_oem_status is 1, send network_adapter_ncsi_reinit')
        skynet.send('network_adapter', 'network_adapter_ncsi_reinit', '') -- 上层服务监听relink信号
        return
    end
    return data
end
function ncsi_core.ncsi_eth_mac_init(mac_str)
    local ret = ncsi_cmd.ncsi_eth_mac_init(mac_str)
    if ret == NCSI_FALSE then
        return false
    end
    return true
end

function ncsi_core.ncsi_set_lldp_status(eth_name, package_id, channel_id, status)
    log:info(
        'ncsi:Set lldp over ncsi status. package_id=%d, channel_d=%d, eth_name=%s, status = %d',
        package_id, channel_id, eth_name, status)
    local ret = ncsi_cmd.ncsi_set_lldp_status(eth_name, package_id, channel_id, status)
    if ret == NCSI_FALSE then
        return false
    end
    return true
end

function ncsi_core.ncsi_enable_vlan_req(package_id, channel_id, eth_name, vlan_mode)
    log:info(
        'ncsi:Set ncsi enable vlan req. package_id=%d, channel_d=%d, eth_name=%s, vlan_mdoe = %d',
        package_id, channel_id, eth_name, vlan_mode) -- 会被循环调用，日志级别改为info
    local ret = ncsi_cmd.ncsi_enable_vlan_req(package_id, channel_id, eth_name, vlan_mode)
    if ret == NCSI_FALSE then
        return false
    end
    return true
end
function ncsi_core.ncsi_disable_vlan_req(package_id, channel_id, eth_name)
    log:info('ncsi:Set ncsi disable vlan req. package_id=%d, channel_d=%d, eth_name=%s', package_id,
        channel_id, eth_name) -- 会被循环调用，日志级别改为info
    local ret = ncsi_cmd.ncsi_disable_vlan_req(package_id, channel_id, eth_name)
    if ret == NCSI_FALSE then
        return false
    end
    return true
end

function ncsi_core.ncsi_get_log(package_id, eth_name, log_dir, time)
    local ret = ncsi_cmd.ncsi_get_log(package_id, eth_name, log_dir, time)
    if ret == NCSI_FALSE then
        return false
    end
    return true
end

function ncsi_core.ncsi_get_log_new(package_id, eth_name, log_dir, time)
    local ret = ncsi_cmd.ncsi_get_log_new(package_id, eth_name, log_dir, time)
    if ret == NCSI_FALSE then
        return false
    end
    return true
end

function ncsi_core.ncsi_get_blackbox(package_id, eth_name, log_name)
    local ret = ncsi_cmd.ncsi_get_blackbox(package_id, eth_name, log_name)
    if ret == NCSI_FALSE then
        return false
    end
    return true
end

function ncsi_core.get_ncsi_channel_cnt()
    local ncsi_channel_cnt = ncsi_cmd.get_ncsi_channel_cnt()
    -- channel数有效范围为1-4
    if ncsi_channel_cnt > 0 and ncsi_channel_cnt < 5 then
        return ncsi_channel_cnt
    end
end

return ncsi_core
