-- 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 type = ProcessingFlow[2].Destination.MediumType
local port_type = cjson.null
if type == 'Copper' then
    port_type = 'ElectricalPort'
elseif type == 'FiberOptic' then
    port_type = 'OpticalPort'
end

local interface_type = cjson.null
if ProcessingFlow[2].Destination.NetDevFuncType == 2 then
    interface_type = ProcessingFlow[2].Destination.FunctionType
end

local is_optical_null = false
local optical_module = cjson.json_object_new_object()
local NPU_MAJOR_PORT_MAP = {
    ['1'] = '1',
    ['2'] = '10',
    ['3'] = '3',
    ['4'] = '12',
    ['5'] = '5',
    ['6'] = '14',
    ['7'] = '7',
    ['8'] = '16',
    ['9'] = '1',
    ['10'] = '10',
    ['11'] = '3',
    ['12'] = '12',
    ['13'] = '5',
    ['14'] = '14',
    ['15'] = '7',
    ['16'] = '16'
}
if ProcessingFlow[2].Destination.MediumType ~= 'FiberOptic' or
    (ProcessingFlow[3].Destination.Presence ~= 1 and ProcessingFlow[9].Destination.Presence ~= 1) then
    is_optical_null = true
elseif ProcessingFlow[5].Destination.Model ~= 'NPU' then
    optical_module['@odata.id'] = '/redfish/v1/Chassis/' .. tostring(Uri.chassisid) .. '/NetworkAdapters/' ..
        tostring(Uri.networkadapterid) .. '/NetworkPorts/' .. tostring(Uri.portid) .. '/OpticalModule'
else
    optical_module['@odata.id'] = '/redfish/v1/Chassis/' .. tostring(Uri.chassisid) ..
        '/Transceivers/OpticalModule_' .. tostring(Uri.networkadapterid) .. 'Port' .. NPU_MAJOR_PORT_MAP[Uri.portid]
end

local port_technology = {}
port_technology[1] = 'Ethernet'
port_technology[2] = 'FibreChannel'
port_technology[4] = 'iSCSI'
port_technology[8] = 'FCoE'
port_technology[16] = 'OPA'
port_technology[32] = 'IB'

local function get_multihost_system_id(card_id, port_id)
    local system_id_table = {
       [1] = {[1] = 3, [2] = 6, [3] = 1, [4] = 8},
       [2] = {[3] = 7, [4] = 2, [1] = 5, [2] = 4}
    }
    return system_id_table[card_id][port_id]
end

local odata_id = cjson.null
if ProcessingFlow[2].Destination.NetDevFuncType == 32 then
    odata_id = '/redfish/v1/Systems/' .. tostring(Uri.chassisid) .. '/EthernetInterfaces/' ..
        tostring(ProcessingFlow[5].Destination.ID) .. 'Port' .. tostring(Uri.portid)
elseif ProcessingFlow[2].Destination.NetDevFuncType == 1 then
    if ProcessingFlow[7].Destination.HostType == 'Multihost' then
        local system_id = get_multihost_system_id(ProcessingFlow[5].Destination.CardId, tonumber(Uri.portid))
        odata_id = '/redfish/v1/Systems/' .. tostring(system_id) .. '/EthernetInterfaces/' ..
            tostring(ProcessingFlow[5].Destination.ID) .. 'Port' .. tostring(Uri.portid)
    else
        odata_id = '/redfish/v1/Systems/' .. tostring(Uri.chassisid) .. '/EthernetInterfaces/' ..
            tostring(ProcessingFlow[5].Destination.ID) .. 'Port' .. tostring(Uri.portid)
    end
end

local function switch_null(input)
    if input == nil or input == '' then
        return cjson.null
    end
    return input
end

local NET_DEV_FUNC_TYPE_FC<const> = 2
local fc_id = cjson.null
local speed_bps = cjson.null
if ProcessingFlow[5].NetDevFuncCapabilities == NET_DEV_FUNC_TYPE_FC then
    fc_id = ProcessingFlow[6].Destination.FCId
    speed_bps = ProcessingFlow[6].Destination.SpeedGbps
end


local oem_info = cjson.json_object_new_object()
local statistic_info = cjson.json_object_new_object()
local lldp_service = cjson.json_object_new_object()
local related_port = cjson.json_object_new_object()

oem_info.PortType = switch_null(port_type)
oem_info.PortMaxSpeed = switch_null(ProcessingFlow[2].Destination.SupportedLinkCapability)
oem_info.PortName = switch_null(ProcessingFlow[2].Destination.Name)
oem_info.InterfaceType = switch_null(interface_type)
oem_info.BDF = switch_null(ProcessingFlow[2].Destination.BDF)
lldp_service.LldpEnabled = switch_null(ProcessingFlow[2].Destination.LLDPEnabled)
lldp_service.WorkMode = "Tx"
oem_info.LldpService = switch_null(lldp_service)
oem_info.FirmwarePackageVersion = switch_null(ProcessingFlow[2].Destination.FirmwareVersion)
oem_info.DriverVersion = switch_null(ProcessingFlow[2].Destination.DriverVersion)
oem_info.DriverName = switch_null(ProcessingFlow[2].Destination.DriverName)
if not is_optical_null then
    oem_info.OpticalModule = switch_null(optical_module)
end
oem_info.PortTechnology = switch_null(port_technology[ProcessingFlow[2].Destination.NetDevFuncType])
oem_info.FCId = switch_null(fc_id)
oem_info.LinkSpeedGbps = switch_null(speed_bps)
related_port['@odata.id'] = odata_id
oem_info.RelatedPort = switch_null(related_port)
statistic_info.TXRateGbps = 0
statistic_info.RXRateGbps = 0
statistic_info.RateNegotiationStage = 'Negotiating'
statistic_info.OpticalModuleEnabled = true
statistic_info.WorkingRate = cjson.null
statistic_info.WorkMode = 'loop'
statistic_info.PeerDeviceCredit = 0
statistic_info.LocalDeviceCredit = 0
statistic_info.PortStatus = 'WaitSignal'
oem_info.StatisticInfo = switch_null(statistic_info)

return oem_info
