/*
 * Copyright 2018-present Open Networking Foundation

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 * http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package omci

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"strings"

	"github.com/google/gopacket"
	"github.com/opencord/bbsim/internal/common"
	"github.com/opencord/omci-lib-go/v2"
	me "github.com/opencord/omci-lib-go/v2/generated"
)

// MibDbEntry contains all the information needed to build a
// MibUploadNextResponse packet.
// if Packet has a value all the other fields are ignored and the packet is sent as is.
type MibDbEntry struct {
	classId  me.ClassID
	entityId EntityID
	params   me.AttributeValueMap
	packet   []byte
}

type MibDb struct {
	NumberOfBaselineCommands uint16
	NumberOfExtendedCommands uint16
	baselineItems            []MibDbEntry
	extendedResponses        [][]byte
}

type EntityID []byte

const (
	unknownMePktReportedMeHdr     string = "002500018000"
	unknownMePktAttributes        string = "0102030405060708090A0B0C0D0E0F101112131415161718191A"
	unknownAttribPktReportedMeHdr string = "0101000007FD"
	unknownAttribPktAttributes    string = "00400801000800000006007F07003F00010001000100"
	extRespMsgContentsLenStart           = 8
	extRespMsgContentsLenEnd             = 10
)

func (e EntityID) ToString() string {
	return hex.EncodeToString(e)
}

func (e EntityID) ToUint16() uint16 {
	return binary.BigEndian.Uint16(e)
}

func (e EntityID) ToUint32() uint32 {
	return binary.BigEndian.Uint32(e)
}

func (e EntityID) FromUint16(id uint16) EntityID {
	buff := new(bytes.Buffer)
	err := binary.Write(buff, binary.BigEndian, id)
	if err != nil {
		panic(err)
	}

	return buff.Bytes()
}

func (e EntityID) Equals(i EntityID) bool {
	if res := bytes.Compare(e, i); res == 0 {
		return true
	}
	return false
}

const (
	cardHolderOnuType byte = 0x01 // ONU is a single piece of integrated equipment
	ethernetUnitType  byte = 0x2f // Ethernet BASE-T
	xgsPonUnitType    byte = 0xee // XG-PON10G10
	gPonUnitType      byte = 0xf5 // GPON12441244
	potsUnitType      byte = 0x20 // POTS
	cardHolderSlotID  byte = 0x01
	tcontSlotId       byte = 0x80 // why is this not the same as the cardHolderSlotID, it does not point to anything
	aniGId            byte = 0x01

	upstreamPriorityQueues   = 8  // Number of queues for each T-CONT
	downstreamPriorityQueues = 16 // Number of queues for each PPTP
	tconts                   = 8  // NOTE will we ever need to configure this?
	// trafficSchedulers        = 8  // NOTE will we ever need to configure this?
)

var (
	cardHolderEntityID  = EntityID{cardHolderOnuType, cardHolderSlotID}
	circuitPackEntityID = cardHolderEntityID // is the same as that of the cardholder ME containing this circuit pack instance
)

func GenerateUniPortEntityId(id uint32) EntityID {
	return EntityID{cardHolderSlotID, byte(id)}
}

// creates a MIB database for a ONU
// CircuitPack and CardHolder are static, everything else can be configured
func GenerateMibDatabase(ethUniPortCount int, potsUniPortCount int, technology common.PonTechnology) (*MibDb, error) {

	mibDb := MibDb{
		baselineItems: []MibDbEntry{},
	}

	// the first element to return is the ONU-Data
	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.OnuDataClassID,
		EntityID{0x00, 0x00},
		me.AttributeValueMap{me.OnuData_MibDataSync: 0}, // FIXME this needs to be parametrized before sending the response
		nil,
	})

	// then we report the CardHolder
	// NOTE we have not report it till now, so leave it commented out
	//mibDb.items = append(mibDb.items, MibDbEntry{
	//	me.CardholderClassID,
	//	cardHolderEntityID,
	//	me.AttributeValueMap{
	//		"ActualPlugInUnitType":   cardHolderOnuType,
	//		"ExpectedPlugInUnitType": ethernetUnitType,
	//	},
	//})

	// ANI circuitPack
	var aniCPType byte

	switch technology {
	case common.XGSPON:
		aniCPType = xgsPonUnitType
	case common.GPON:
		aniCPType = gPonUnitType
	}

	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.CircuitPackClassID,
		circuitPackEntityID,
		me.AttributeValueMap{
			me.CircuitPack_Type:          aniCPType,
			me.CircuitPack_NumberOfPorts: 1, // NOTE is this the ANI port? must be
			me.CircuitPack_SerialNumber:  ToOctets("BBSM-Circuit-Pack-ani", 20),
			me.CircuitPack_Version:       ToOctets("v0.0.1", 20),
		},
		nil,
	})
	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.CircuitPackClassID,
		circuitPackEntityID,
		me.AttributeValueMap{
			me.CircuitPack_VendorId:            ToOctets("ONF", 4),
			me.CircuitPack_AdministrativeState: 0,
			me.CircuitPack_OperationalState:    0,
			me.CircuitPack_BridgedOrIpInd:      0,
		},
		nil,
	})
	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.CircuitPackClassID,
		circuitPackEntityID,
		me.AttributeValueMap{
			me.CircuitPack_EquipmentId:                 ToOctets("BBSM-Circuit-Pack", 20),
			me.CircuitPack_CardConfiguration:           0,
			me.CircuitPack_TotalTContBufferNumber:      8,
			me.CircuitPack_TotalPriorityQueueNumber:    8,
			me.CircuitPack_TotalTrafficSchedulerNumber: 0,
		},
		nil,
	})
	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.CircuitPackClassID,
		circuitPackEntityID,
		me.AttributeValueMap{
			me.CircuitPack_PowerShedOverride: uint32(0),
		},
		nil,
	})

	// ANI-G
	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.AniGClassID,
		EntityID{tcontSlotId, aniGId},
		me.AttributeValueMap{
			me.AniG_Arc:                         0,
			me.AniG_ArcInterval:                 0,
			me.AniG_Deprecated:                  0,
			me.AniG_GemBlockLength:              48,
			me.AniG_LowerOpticalThreshold:       255,
			me.AniG_LowerTransmitPowerThreshold: 129,
			me.AniG_OnuResponseTime:             0,
			me.AniG_OpticalSignalLevel:          57428,
			me.AniG_PiggybackDbaReporting:       0,
			me.AniG_SignalDegradeThreshold:      9,
			me.AniG_SignalFailThreshold:         5,
			me.AniG_SrIndication:                1,
			me.AniG_TotalTcontNumber:            8,
			me.AniG_TransmitOpticalLevel:        3171,
			me.AniG_UpperOpticalThreshold:       255,
			me.AniG_UpperTransmitPowerThreshold: 129,
		},
		nil,
	})

	// circuitPack Ethernet
	// NOTE the circuit pack is divided in multiple messages as too big to fit in a single one
	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.CircuitPackClassID,
		circuitPackEntityID,
		me.AttributeValueMap{
			me.CircuitPack_Type:          ethernetUnitType,
			me.CircuitPack_NumberOfPorts: ethUniPortCount,
			me.CircuitPack_SerialNumber:  ToOctets("BBSM-Circuit-Pack", 20),
			me.CircuitPack_Version:       ToOctets("v0.0.1", 20),
		},
		nil,
	})
	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.CircuitPackClassID,
		circuitPackEntityID,
		me.AttributeValueMap{
			me.CircuitPack_VendorId:            ToOctets("ONF", 4),
			me.CircuitPack_AdministrativeState: 0,
			me.CircuitPack_OperationalState:    0,
			me.CircuitPack_BridgedOrIpInd:      0,
		},
		nil,
	})
	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.CircuitPackClassID,
		circuitPackEntityID,
		me.AttributeValueMap{
			me.CircuitPack_EquipmentId:                 ToOctets("BBSM-Circuit-Pack", 20),
			me.CircuitPack_CardConfiguration:           0,
			me.CircuitPack_TotalTContBufferNumber:      8,
			me.CircuitPack_TotalPriorityQueueNumber:    8,
			me.CircuitPack_TotalTrafficSchedulerNumber: 16,
		},
		nil,
	})
	mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
		me.CircuitPackClassID,
		circuitPackEntityID,
		me.AttributeValueMap{
			me.CircuitPack_PowerShedOverride: uint32(0),
		},
		nil,
	})

	if potsUniPortCount > 0 {
		// circuitPack POTS
		// NOTE the circuit pack is divided in multiple messages as too big to fit in a single one
		mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
			me.CircuitPackClassID,
			circuitPackEntityID,
			me.AttributeValueMap{
				me.CircuitPack_Type:          potsUnitType,
				me.CircuitPack_NumberOfPorts: potsUniPortCount,
				me.CircuitPack_SerialNumber:  ToOctets("BBSM-Circuit-Pack", 20),
				me.CircuitPack_Version:       ToOctets("v0.0.1", 20),
			},
			nil,
		})
		mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
			me.CircuitPackClassID,
			circuitPackEntityID,
			me.AttributeValueMap{
				me.CircuitPack_VendorId:            ToOctets("ONF", 4),
				me.CircuitPack_AdministrativeState: 0,
				me.CircuitPack_OperationalState:    0,
				me.CircuitPack_BridgedOrIpInd:      0,
			},
			nil,
		})
		mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
			me.CircuitPackClassID,
			circuitPackEntityID,
			me.AttributeValueMap{
				me.CircuitPack_EquipmentId:                 ToOctets("BBSM-Circuit-Pack", 20),
				me.CircuitPack_CardConfiguration:           0,
				me.CircuitPack_TotalTContBufferNumber:      8,
				me.CircuitPack_TotalPriorityQueueNumber:    8,
				me.CircuitPack_TotalTrafficSchedulerNumber: 16,
			},
			nil,
		})
		mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
			me.CircuitPackClassID,
			circuitPackEntityID,
			me.AttributeValueMap{
				me.CircuitPack_PowerShedOverride: uint32(0),
			},
			nil,
		})
	}

	// PPTP and UNI-Gs
	// NOTE this are dependent on the number of UNI this ONU supports
	// Through an identical ID, the UNI-G ME is implicitly linked to an instance of a PPTP
	totalPortsCount := ethUniPortCount + potsUniPortCount
	for i := 1; i <= totalPortsCount; i++ {
		uniEntityId := GenerateUniPortEntityId(uint32(i))

		if i <= ethUniPortCount {
			// first, create the correct amount of ethernet UNIs, the same is done in onu.go
			mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
				me.PhysicalPathTerminationPointEthernetUniClassID,
				uniEntityId,
				me.AttributeValueMap{
					me.PhysicalPathTerminationPointEthernetUni_ExpectedType:                  0,
					me.PhysicalPathTerminationPointEthernetUni_SensedType:                    ethernetUnitType,
					me.PhysicalPathTerminationPointEthernetUni_AutoDetectionConfiguration:    0,
					me.PhysicalPathTerminationPointEthernetUni_EthernetLoopbackConfiguration: 0,
					me.PhysicalPathTerminationPointEthernetUni_AdministrativeState:           0,
					me.PhysicalPathTerminationPointEthernetUni_OperationalState:              0,
					me.PhysicalPathTerminationPointEthernetUni_ConfigurationInd:              3,
					me.PhysicalPathTerminationPointEthernetUni_MaxFrameSize:                  1518,
					me.PhysicalPathTerminationPointEthernetUni_DteOrDceInd:                   0,
					me.PhysicalPathTerminationPointEthernetUni_PauseTime:                     0,
					me.PhysicalPathTerminationPointEthernetUni_BridgedOrIpInd:                2,
					me.PhysicalPathTerminationPointEthernetUni_Arc:                           0,
					me.PhysicalPathTerminationPointEthernetUni_ArcInterval:                   0,
					me.PhysicalPathTerminationPointEthernetUni_PppoeFilter:                   0,
					me.PhysicalPathTerminationPointEthernetUni_PowerControl:                  0,
				},
				nil,
			})
		} else {
			// the remaining ones are pots UNIs, the same is done in onu.go
			mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
				me.PhysicalPathTerminationPointPotsUniClassID,
				uniEntityId,
				me.AttributeValueMap{
					me.PhysicalPathTerminationPointPotsUni_AdministrativeState: 0,
					me.PhysicalPathTerminationPointPotsUni_Deprecated:          0,
					me.PhysicalPathTerminationPointPotsUni_Arc:                 0,
					me.PhysicalPathTerminationPointPotsUni_ArcInterval:         0,
					me.PhysicalPathTerminationPointPotsUni_Impedance:           0,
					me.PhysicalPathTerminationPointPotsUni_TransmissionPath:    0,
					me.PhysicalPathTerminationPointPotsUni_RxGain:              0,
					me.PhysicalPathTerminationPointPotsUni_TxGain:              0,
					me.PhysicalPathTerminationPointPotsUni_OperationalState:    0,
					me.PhysicalPathTerminationPointPotsUni_HookState:           0,
					me.PhysicalPathTerminationPointPotsUni_PotsHoldoverTime:    0,
					me.PhysicalPathTerminationPointPotsUni_NominalFeedVoltage:  0,
					me.PhysicalPathTerminationPointPotsUni_LossOfSoftswitch:    0,
				},
				nil,
			})
		}

		mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
			me.UniGClassID,
			uniEntityId,
			me.AttributeValueMap{
				me.UniG_AdministrativeState:         0,
				me.UniG_Deprecated:                  0,
				me.UniG_ManagementCapability:        0,
				me.UniG_NonOmciManagementIdentifier: 0,
				me.UniG_RelayAgentOptions:           0,
			},
			nil,
		})

		// Downstream Queues (related to PPTP)
		// 16 priorities queues for each UNI Ports
		// EntityID = cardHolderSlotID + Uni EntityID (0101)
		for j := 1; j <= downstreamPriorityQueues; j++ {
			queueEntityId := EntityID{cardHolderSlotID, byte(j)}

			// we first report the PriorityQueue without any attribute
			mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
				me.PriorityQueueClassID,
				queueEntityId, //was not reported in the original implementation
				me.AttributeValueMap{},
				nil,
			})

			// then we report it with the required attributes
			// In the downstream direction, the first byte is the slot number and the second byte is the port number of the queue's destination port.
			relatedPort := append(uniEntityId, 0x00, byte(j))
			mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
				me.PriorityQueueClassID,
				queueEntityId, //was not reported in the original implementation
				me.AttributeValueMap{
					me.PriorityQueue_QueueConfigurationOption:                            0,
					me.PriorityQueue_MaximumQueueSize:                                    100,
					me.PriorityQueue_AllocatedQueueSize:                                  100,
					me.PriorityQueue_DiscardBlockCounterResetInterval:                    0,
					me.PriorityQueue_ThresholdValueForDiscardedBlocksDueToBufferOverflow: 0,
					me.PriorityQueue_RelatedPort:                                         relatedPort.ToUint32(),
					me.PriorityQueue_TrafficSchedulerPointer:                             0, //it was hardcoded to 0x0108 in the current implementation
					me.PriorityQueue_Weight:                                              1,
					me.PriorityQueue_BackPressureOperation:                               1,
					me.PriorityQueue_BackPressureTime:                                    0,
					me.PriorityQueue_BackPressureOccurQueueThreshold:                     0,
					me.PriorityQueue_BackPressureClearQueueThreshold:                     0,
				},
				nil,
			})
		}
	}

	// T-CONTS and Traffic Schedulers
	for i := 1; i <= tconts; i++ {
		tcontEntityId := EntityID{tcontSlotId, byte(i)}

		mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
			me.TContClassID,
			tcontEntityId,
			me.AttributeValueMap{
				me.TCont_AllocId: 65535,
			},
			nil,
		})

		tsEntityId := EntityID{cardHolderSlotID, byte(i)}
		mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
			me.TrafficSchedulerClassID,
			tsEntityId, //was not reported in the original implementation
			me.AttributeValueMap{
				me.TrafficScheduler_TContPointer:            tcontEntityId.ToUint16(), // was hardcoded to a non-existing t-cont
				me.TrafficScheduler_TrafficSchedulerPointer: 0,
				me.TrafficScheduler_Policy:                  02,
				me.TrafficScheduler_PriorityWeight:          0,
			},
			nil,
		})

		for j := 1; j <= upstreamPriorityQueues; j++ {
			queueEntityId := EntityID{tcontSlotId, byte(j)}
			// Upstream Queues (related to traffic schedulers)
			// 8 priorities queues per TCONT
			// EntityID = tcontSlotId + Uni EntityID (8001)

			// we first report the PriorityQueue without any attribute
			mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
				me.PriorityQueueClassID,
				queueEntityId, //was not reported in the original implementation
				me.AttributeValueMap{},
				nil,
			})

			// then we report it with the required attributes
			// In the upstream direction, the first 2 bytes are the ME ID of the associated T- CONT, the first byte of which is a slot number, the second byte a T-CONT number.
			relatedPort := append(tcontEntityId, 0x00, byte(j))
			mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
				me.PriorityQueueClassID,
				queueEntityId, //was not reported in the original implementation
				me.AttributeValueMap{
					me.PriorityQueue_QueueConfigurationOption:                            0,
					me.PriorityQueue_MaximumQueueSize:                                    100,
					me.PriorityQueue_AllocatedQueueSize:                                  100,
					me.PriorityQueue_DiscardBlockCounterResetInterval:                    0,
					me.PriorityQueue_ThresholdValueForDiscardedBlocksDueToBufferOverflow: 0,
					me.PriorityQueue_RelatedPort:                                         relatedPort.ToUint32(),
					me.PriorityQueue_TrafficSchedulerPointer:                             tsEntityId.ToUint16(), //it was hardcoded to 0x0108 in the current implementation
					me.PriorityQueue_Weight:                                              1,
					me.PriorityQueue_BackPressureOperation:                               1,
					me.PriorityQueue_BackPressureTime:                                    0,
					me.PriorityQueue_BackPressureOccurQueueThreshold:                     0,
					me.PriorityQueue_BackPressureClearQueueThreshold:                     0,
				},
				nil,
			})
		}
	}

	// ONU-2g

	onu2g := MibDbEntry{
		me.Onu2GClassID,
		EntityID{0x00, 0x00},
		me.AttributeValueMap{
			//me.Onu2G_EquipmentId: 1,
			//me.Onu2G_OpticalNetworkUnitManagementAndControlChannelOmccVersion: 2,
			//me.Onu2G_VendorProductCode: 3,
			//me.Onu2G_SecurityCapability: 4,
			//me.Onu2G_SecurityMode: 5,

			me.Onu2G_TotalPriorityQueueNumber:                    64,
			me.Onu2G_TotalTrafficSchedulerNumber:                 8,
			me.Onu2G_Deprecated:                                  1,
			me.Onu2G_TotalGemPortIdNumber:                        8,
			me.Onu2G_Sysuptime:                                   6,
			me.Onu2G_ConnectivityCapability:                      127,
			me.Onu2G_CurrentConnectivityMode:                     7,
			me.Onu2G_QualityOfServiceQosConfigurationFlexibility: 63,
			me.Onu2G_PriorityQueueScaleFactor:                    1,
		},
		nil,
	}

	if common.Config.BBSim.InjectOmciUnknownAttributes {
		onu2g = MibDbEntry{
			me.Onu2GClassID,
			nil,
			me.AttributeValueMap{},
			[]byte{129, 41, 46, 10, 0, 2, 0, 0, 1, 1, 0, 0, 7, 253, 0, 64, 8, 1, 0, 8, 0, 0, 0, 6, 0, 127, 7, 0, 63, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 40},
		}
	}

	mibDb.baselineItems = append(mibDb.baselineItems, onu2g)

	if common.Config.BBSim.InjectOmciUnknownMe {
		// NOTE the TxID is actually replaced
		// by SetTxIdInEncodedPacket in CreateMibUploadNextResponse
		txId := uint16(33066)

		b := make([]byte, 4)
		binary.BigEndian.PutUint16(b, txId)
		b[2] = byte(omci.MibUploadNextResponseType)
		b[3] = byte(omci.BaselineIdent)
		omciHdr := hex.EncodeToString(b)

		//omciHdr := "00032e0a"
		msgHdr := "00020000"
		trailer := "0000002828ce00e2"
		msg := omciHdr + msgHdr + unknownMePktReportedMeHdr + unknownMePktAttributes + trailer
		data, err := hex.DecodeString(msg)
		if err != nil {
			omciLogger.Fatal("cannot-create-custom-packet")
		}

		packet := gopacket.NewPacket(data, omci.LayerTypeOMCI, gopacket.Lazy)

		mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
			me.ClassID(37), // G.988 "Intentionally left blank"
			nil,
			me.AttributeValueMap{},
			packet.Data(),
		})
	}

	mibDb.NumberOfBaselineCommands = uint16(len(mibDb.baselineItems))

	// Create extended MIB upload responses
	omciLayer := &omci.OMCI{
		TransactionID:    0xFFFF, //to be replaced later on
		MessageType:      omci.MibUploadNextResponseType,
		DeviceIdentifier: omci.ExtendedIdent,
	}
	var i uint16 = 0
	for i < mibDb.NumberOfBaselineCommands {
		currentEntry := mibDb.baselineItems[i]
		for mibDb.baselineItems[i].packet != nil {
			// Skip any entry with a predefined packet currently used for MEs with unknown ClassID or unknown attributes.
			// This information will be added later to the last extended response packet
			i++
			currentEntry = mibDb.baselineItems[i]
		}
		reportedME, meErr := me.LoadManagedEntityDefinition(currentEntry.classId, me.ParamData{
			EntityID:   currentEntry.entityId.ToUint16(),
			Attributes: currentEntry.params,
		})
		if meErr.GetError() != nil {
			omciLogger.Errorf("Error while generating reportedME %s: %v", currentEntry.classId.String(), meErr.Error())
		}
		request := &omci.MibUploadNextResponse{
			MeBasePacket: omci.MeBasePacket{
				EntityClass:    me.OnuDataClassID,
				EntityInstance: uint16(0),
				Extended:       true,
			},
			ReportedME:    *reportedME,
			AdditionalMEs: make([]me.ManagedEntity, 0),
		}
		i++
		var outgoingPacket []byte
		var outgoingPacketLen = 0
	addMeLoop:
		for outgoingPacketLen <= omci.MaxExtendedLength-omci.MaxBaselineLength && i < mibDb.NumberOfBaselineCommands {
			currentEntry := mibDb.baselineItems[i]
			for mibDb.baselineItems[i].packet != nil {
				// Skip any entry with a predefined packet currently used for MEs with unknown ClassID or unknown attributes.
				// This information will be added later to the last extended response packet
				i++
				if i < mibDb.NumberOfBaselineCommands {
					currentEntry = mibDb.baselineItems[i]
				} else {
					break addMeLoop
				}
			}
			additionalME, meErr := me.LoadManagedEntityDefinition(currentEntry.classId, me.ParamData{
				EntityID:   currentEntry.entityId.ToUint16(),
				Attributes: currentEntry.params,
			})
			if meErr.GetError() != nil {
				omciLogger.Errorf("Error while generating additionalME %s: %v", currentEntry.classId.String(), meErr.Error())
			}
			request.AdditionalMEs = append(request.AdditionalMEs, *additionalME)

			var options gopacket.SerializeOptions
			options.FixLengths = true

			buffer := gopacket.NewSerializeBuffer()
			omciErr := gopacket.SerializeLayers(buffer, options, omciLayer, request)
			if omciErr != nil {
				omciLogger.Errorf("Error while serializing generating additionalME %s: %v", currentEntry.classId.String(), omciErr)
			}
			outgoingPacket = buffer.Bytes()
			outgoingPacketLen = len(outgoingPacket)
			i++
		}
		mibDb.extendedResponses = append(mibDb.extendedResponses, outgoingPacket)
		mibDb.NumberOfExtendedCommands = uint16(len(mibDb.extendedResponses))

		outgoingPacketString := strings.ToLower(hex.EncodeToString(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1]))
		omciLogger.Debugf("Extended MIB upload response respNo: %d length: %d  string: %s", mibDb.NumberOfExtendedCommands, outgoingPacketLen, outgoingPacketString)
	}
	// Currently, there is enough space in the last extended response to add potential MEs with unknown ClassID or unknown attributes, if requested.
	if common.Config.BBSim.InjectOmciUnknownMe {
		var err error
		mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], err = AppendAdditionalMEs(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], unknownMePktReportedMeHdr, unknownMePktAttributes)
		if err != nil {
			omciLogger.Fatal(err)
		} else {
			outgoingPacketString := strings.ToLower(hex.EncodeToString(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1]))
			omciLogger.Debugf("Reponse with unknown ME added: %s", outgoingPacketString)
		}
	}
	if common.Config.BBSim.InjectOmciUnknownAttributes {
		var err error
		mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], err = AppendAdditionalMEs(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], unknownAttribPktReportedMeHdr, unknownAttribPktAttributes)
		if err != nil {
			omciLogger.Fatal(err)
		} else {
			outgoingPacketString := strings.ToLower(hex.EncodeToString(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1]))
			omciLogger.Debugf("Reponse with unknown attributes added: %s", outgoingPacketString)
		}
	}
	return &mibDb, nil
}

func AppendAdditionalMEs(srcSlice []byte, reportedMeHdr string, attributes string) ([]byte, error) {
	attribBytes, err := hex.DecodeString(attributes)
	if err != nil {
		return nil, fmt.Errorf("cannot-decode-attributes-string")
	}
	attribBytesLen := len(attribBytes)
	attribBytesLenStr := fmt.Sprintf("%04X", attribBytesLen)
	msg := attribBytesLenStr + reportedMeHdr + attributes
	data, err := hex.DecodeString(msg)
	if err != nil {
		return nil, fmt.Errorf("cannot-decode-attributes")
	}
	dstSlice := make([]byte, len(srcSlice))
	copy(dstSlice, srcSlice)
	dstSlice = append(dstSlice[:], data[:]...)
	messageContentsLen := binary.BigEndian.Uint16(dstSlice[extRespMsgContentsLenStart:extRespMsgContentsLenEnd])
	dataLen := len(data)
	newMessageContentsLen := messageContentsLen + uint16(dataLen)
	newLenSlice := make([]byte, 2)
	binary.BigEndian.PutUint16(newLenSlice, newMessageContentsLen)
	copy(dstSlice[extRespMsgContentsLenStart:extRespMsgContentsLenEnd], newLenSlice[0:2])
	return dstSlice, nil
}
