/*
 * 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 (
	"encoding/hex"
	"errors"
	"fmt"
	"math/rand"
	"strconv"

	"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"
	"github.com/opencord/voltha-protos/v5/go/openolt"
	log "github.com/sirupsen/logrus"
)

func ParseGetRequest(omciPkt gopacket.Packet) (*omci.GetRequest, error) {
	msgLayer := omciPkt.Layer(omci.LayerTypeGetRequest)
	if msgLayer == nil {
		err := "omci Msg layer could not be detected for LayerTypeGetRequest"
		omciLogger.Error(err)
		return nil, errors.New(err)
	}
	msgObj, msgOk := msgLayer.(*omci.GetRequest)
	if !msgOk {
		err := "omci Msg layer could not be assigned for LayerTypeGetRequest"
		omciLogger.Error(err)
		return nil, errors.New(err)
	}
	return msgObj, nil
}

func CreateGetResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI, onuSn *openolt.SerialNumber, mds uint8,
	activeImageEntityId uint16, committedImageEntityId uint16, standbyImageVersion string, activeImageVersion string,
	committedImageVersion string, onuDown bool) ([]byte, error) {
	msgObj, err := ParseGetRequest(omciPkt)
	if err != nil {
		return nil, err
	}
	omciLogger.WithFields(log.Fields{
		"DeviceIdent":    omciMsg.DeviceIdentifier,
		"EntityClass":    msgObj.EntityClass,
		"EntityInstance": msgObj.EntityInstance,
		"AttributeMask":  fmt.Sprintf("%x", msgObj.AttributeMask),
	}).Trace("received-omci-get-request")

	var response *omci.GetResponse

	isExtended := false
	if omciMsg.DeviceIdentifier == omci.ExtendedIdent {
		isExtended = true
	}
	switch msgObj.EntityClass {
	case me.Onu2GClassID:
		response = createOnu2gResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance)
	case me.OnuGClassID:
		response = createOnugResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance, onuSn)
	case me.SoftwareImageClassID:
		response = createSoftwareImageResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance,
			activeImageEntityId, committedImageEntityId, standbyImageVersion, activeImageVersion, committedImageVersion)
	case me.IpHostConfigDataClassID:
		response = createIpHostResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance)
	case me.VoipConfigDataClassID:
		response = createVoipConfigDataResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance)
	case me.UniGClassID:
		response = createUnigResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance, onuDown)
	case me.PhysicalPathTerminationPointEthernetUniClassID:
		response = createPptpEthernetResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance, onuDown)
	case me.PhysicalPathTerminationPointPotsUniClassID:
		response = createPptpPotsResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance, onuDown)
	case me.AniGClassID:
		response = createAnigResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance)
	case me.OnuDataClassID:
		response = createOnuDataResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance, mds)
	case me.EthernetFramePerformanceMonitoringHistoryDataUpstreamClassID:
		response = createEthernetFramePerformanceMonitoringHistoryDataUpstreamResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance)
	case me.EthernetFramePerformanceMonitoringHistoryDataDownstreamClassID:
		response = createEthernetFramePerformanceMonitoringHistoryDataDownstreamResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance)
	case me.EthernetPerformanceMonitoringHistoryDataClassID:
		response = createEthernetPerformanceMonitoringHistoryDataResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance)
	case me.FecPerformanceMonitoringHistoryDataClassID:
		response = createFecPerformanceMonitoringHistoryDataResponse(isExtended, msgObj.AttributeMask, msgObj.EntityInstance)
	case me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID:
		response = createGemPortNetworkCtpPerformanceMonitoringHistoryData(isExtended, msgObj.AttributeMask, msgObj.EntityInstance)
	case me.EthernetFrameExtendedPmClassID,
		me.EthernetFrameExtendedPm64BitClassID:
		response = createEthernetFrameExtendedPmGetResponse(isExtended, msgObj.EntityClass, msgObj.AttributeMask, msgObj.EntityInstance)
	default:
		omciLogger.WithFields(log.Fields{
			"EntityClass":    msgObj.EntityClass,
			"EntityInstance": msgObj.EntityInstance,
			"AttributeMask":  fmt.Sprintf("%x", msgObj.AttributeMask),
		}).Warnf("do-not-know-how-to-handle-get-request-for-me-class")
		return nil, nil
	}
	omciLayer := &omci.OMCI{
		TransactionID:    omciMsg.TransactionID,
		MessageType:      omci.GetResponseType,
		DeviceIdentifier: omciMsg.DeviceIdentifier,
	}
	var options gopacket.SerializeOptions
	options.FixLengths = true

	buffer := gopacket.NewSerializeBuffer()
	err = gopacket.SerializeLayers(buffer, options, omciLayer, response)
	if err != nil {
		omciLogger.WithFields(log.Fields{
			"Err":  err,
			"TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
		}).Error("cannot-Serialize-GetResponse")
		return nil, err
	}
	pkt := buffer.Bytes()

	log.WithFields(log.Fields{
		"TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
		"pkt":  hex.EncodeToString(pkt),
	}).Trace("omci-get-response")

	return pkt, nil
}

func createOnu2gResponse(isExtended bool, attributeMask uint16, entityID uint16) *omci.GetResponse {

	managedEntity, meErr := me.NewOnu2G(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID:   entityID,
			me.Onu2G_EquipmentId: ToOctets("12345123451234512345", 20),
			me.Onu2G_OpticalNetworkUnitManagementAndControlChannelOmccVersion: common.Config.BBSim.OmccVersion,
			me.Onu2G_VendorProductCode:                                        0,
			me.Onu2G_SecurityCapability:                                       1,
			me.Onu2G_SecurityMode:                                             1,
			me.Onu2G_TotalPriorityQueueNumber:                                 1,
			me.Onu2G_TotalTrafficSchedulerNumber:                              1,
			me.Onu2G_Deprecated:                                               1,
			me.Onu2G_TotalGemPortIdNumber:                                     32,
			me.Onu2G_Sysuptime:                                                319389947, // NOTE need to be smarter?
			me.Onu2G_ConnectivityCapability:                                   127,
			me.Onu2G_CurrentConnectivityMode:                                  5,
			me.Onu2G_QualityOfServiceQosConfigurationFlexibility:              48,
			me.Onu2G_PriorityQueueScaleFactor:                                 1,
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewOnu2G %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.Onu2GClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createOnugResponse(isExtended bool, attributeMask uint16, entityID uint16, onuSn *openolt.SerialNumber) *omci.GetResponse {

	managedEntity, meErr := me.NewOnuG(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID:              entityID,
			me.OnuG_VendorId:                ToOctets("BBSM", 4),
			me.OnuG_Version:                 ToOctets("v0.0.1", 14),
			me.OnuG_SerialNumber:            append(onuSn.VendorId, onuSn.VendorSpecific...),
			me.OnuG_TrafficManagementOption: 0,
			me.OnuG_Deprecated:              0,
			me.OnuG_BatteryBackup:           0,
			me.OnuG_AdministrativeState:     0,
			me.OnuG_OperationalState:        0,
			me.OnuG_OnuSurvivalTime:         10,
			me.OnuG_LogicalOnuId:            ToOctets("BBSM", 24),
			me.OnuG_LogicalPassword:         ToOctets("BBSM", 12),
			me.OnuG_CredentialsStatus:       0,
			me.OnuG_ExtendedTcLayerOptions:  0,
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewOnu2G %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.OnuGClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createSoftwareImageResponse(isExtended bool, attributeMask uint16, entityInstance uint16, activeImageEntityId uint16,
	committedImageEntityId uint16, standbyImageVersion string, activeImageVersion string, committedImageVersion string) *omci.GetResponse {

	omciLogger.WithFields(log.Fields{
		"EntityInstance": entityInstance,
		"AttributeMask":  attributeMask,
	}).Trace("received-get-software-image-request")

	// Only one image can be active and committed
	committed := 0
	active := 0
	version := standbyImageVersion
	if entityInstance == activeImageEntityId {
		active = 1
		version = activeImageVersion
	}
	if entityInstance == committedImageEntityId {
		committed = 1
		version = committedImageVersion
	}

	imageHash, err := hex.DecodeString(hex.EncodeToString([]byte(version)))
	if err != nil {
		omciLogger.WithFields(log.Fields{
			"entityId":  entityInstance,
			"active":    active,
			"committed": committed,
			"err":       err,
		}).Error("cannot-generate-image-hash")
	}

	// NOTE that we need send the response for the correct ME Instance or the adapter won't process it
	res := &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.SoftwareImageClassID,
			EntityInstance: entityInstance,
			Extended:       isExtended,
		},
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID:           0,
			me.SoftwareImage_Version:     ToOctets(version, 14),
			me.SoftwareImage_IsCommitted: committed,
			me.SoftwareImage_IsActive:    active,
			me.SoftwareImage_IsValid:     1,
			me.SoftwareImage_ProductCode: ToOctets("BBSIM-ONU", 25),
			me.SoftwareImage_ImageHash:   imageHash,
		},
		Result:        me.Success,
		AttributeMask: attributeMask,
	}

	omciLogger.WithFields(log.Fields{
		"omciMessage": res,
		"entityId":    entityInstance,
		"active":      active,
		"committed":   committed,
	}).Trace("Reporting SoftwareImage")

	return res
}

func createIpHostResponse(isExtended bool, attributeMask uint16, entityInstance uint16) *omci.GetResponse {
	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.IpHostConfigDataClassID,
			EntityInstance: entityInstance,
			Extended:       isExtended,
		},
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID:             0,
			me.IpHostConfigData_MacAddress: ToOctets("aabbcc", 6),
		},
		Result:        me.Success,
		AttributeMask: attributeMask,
	}
}

func createVoipConfigDataResponse(isExtended bool, attributeMask uint16, entityInstance uint16) *omci.GetResponse {
	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.VoipConfigDataClassID,
			EntityInstance: entityInstance,
			Extended:       isExtended,
		},
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID: 0,
			me.VoipConfigData_AvailableSignallingProtocols:      1,
			me.VoipConfigData_SignallingProtocolUsed:            1,
			me.VoipConfigData_AvailableVoipConfigurationMethods: 1,
			me.VoipConfigData_VoipConfigurationMethodUsed:       1,
			me.VoipConfigData_VoipConfigurationAddressPointer:   0xFFFF,
			me.VoipConfigData_VoipConfigurationState:            0,
			me.VoipConfigData_RetrieveProfile:                   0,
			me.VoipConfigData_ProfileVersion:                    0,
		},
		Result:        me.Success,
		AttributeMask: attributeMask,
	}
}

func createUnigResponse(isExtended bool, attributeMask uint16, entityID uint16, onuDown bool) *omci.GetResponse {
	// Valid values for uni_admin_state are 0 (unlocks) and 1 (locks)
	omciAdminState := 1
	if !onuDown {
		omciAdminState = 0
	}
	managedEntity, meErr := me.NewUniG(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID:                  entityID,
			me.UniG_Deprecated:                  0,
			me.UniG_AdministrativeState:         omciAdminState,
			me.UniG_ManagementCapability:        0,
			me.UniG_NonOmciManagementIdentifier: 1,
			me.UniG_RelayAgentOptions:           1,
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewUniG %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.UniGClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createPptpEthernetResponse(isExtended bool, attributeMask uint16, entityID uint16, onuDown bool) *omci.GetResponse {
	// Valid values for oper_state are 0 (enabled) and 1 (disabled)
	// Valid values for uni_admin_state are 0 (unlocks) and 1 (locks)
	onuAdminState := 1
	if !onuDown {
		onuAdminState = 0
	}
	onuOperState := onuAdminState // For now make the assumption that oper state reflects the admin state
	managedEntity, meErr := me.NewPhysicalPathTerminationPointEthernetUni(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID: entityID,
			me.PhysicalPathTerminationPointEthernetUni_ExpectedType:                  0,
			me.PhysicalPathTerminationPointEthernetUni_SensedType:                    0,
			me.PhysicalPathTerminationPointEthernetUni_AutoDetectionConfiguration:    0,
			me.PhysicalPathTerminationPointEthernetUni_EthernetLoopbackConfiguration: 0,
			me.PhysicalPathTerminationPointEthernetUni_AdministrativeState:           onuAdminState,
			me.PhysicalPathTerminationPointEthernetUni_OperationalState:              onuOperState,
			me.PhysicalPathTerminationPointEthernetUni_ConfigurationInd:              0,
			me.PhysicalPathTerminationPointEthernetUni_MaxFrameSize:                  0,
			me.PhysicalPathTerminationPointEthernetUni_DteOrDceInd:                   0,
			me.PhysicalPathTerminationPointEthernetUni_PauseTime:                     0,
			me.PhysicalPathTerminationPointEthernetUni_BridgedOrIpInd:                0,
			me.PhysicalPathTerminationPointEthernetUni_Arc:                           0,
			me.PhysicalPathTerminationPointEthernetUni_ArcInterval:                   0,
			me.PhysicalPathTerminationPointEthernetUni_PppoeFilter:                   0,
			me.PhysicalPathTerminationPointEthernetUni_PowerControl:                  0,
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewPhysicalPathTerminationPointEthernetUni %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.PhysicalPathTerminationPointEthernetUniClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createPptpPotsResponse(isExtended bool, attributeMask uint16, entityID uint16, onuDown bool) *omci.GetResponse {
	// Valid values for oper_state are 0 (enabled) and 1 (disabled)
	// Valid values for uni_admin_state are 0 (unlocks) and 1 (locks)
	onuAdminState := 1
	if !onuDown {
		onuAdminState = 0
	}
	onuOperState := onuAdminState // For now make the assumption that oper state reflects the admin state
	managedEntity, meErr := me.NewPhysicalPathTerminationPointPotsUni(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID: entityID,
			me.PhysicalPathTerminationPointPotsUni_AdministrativeState: onuAdminState,
			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:    onuOperState,
			me.PhysicalPathTerminationPointPotsUni_HookState:           0,
			me.PhysicalPathTerminationPointPotsUni_PotsHoldoverTime:    0,
			me.PhysicalPathTerminationPointPotsUni_NominalFeedVoltage:  0,
			me.PhysicalPathTerminationPointPotsUni_LossOfSoftswitch:    0,
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewPhysicalPathTerminationPointPotsUni %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.PhysicalPathTerminationPointPotsUniClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createEthernetFramePerformanceMonitoringHistoryDataUpstreamResponse(isExtended bool, attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewEthernetFramePerformanceMonitoringHistoryDataUpstream(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID: entityID,
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_IntervalEndTime:         0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_ThresholdData12Id:       0,
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_DropEvents:              rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_Octets:                  rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_Packets:                 rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_BroadcastPackets:        rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_MulticastPackets:        rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_CrcErroredPackets:       rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_UndersizePackets:        rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_OversizePackets:         rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_Packets64Octets:         rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_Packets65To127Octets:    rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_Packets128To255Octets:   rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_Packets256To511Octets:   rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_Packets512To1023Octets:  rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataUpstream_Packets1024To1518Octets: rand.Intn(100),
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewEthernetFramePerformanceMonitoringHistoryDataUpstream %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.EthernetFramePerformanceMonitoringHistoryDataUpstreamClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createEthernetFramePerformanceMonitoringHistoryDataDownstreamResponse(isExtended bool, attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewEthernetFramePerformanceMonitoringHistoryDataDownstream(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID: entityID,
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_IntervalEndTime:         0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_ThresholdData12Id:       0,
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_DropEvents:              rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_Octets:                  rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_Packets:                 rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_BroadcastPackets:        rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_MulticastPackets:        rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_CrcErroredPackets:       rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_UndersizePackets:        rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_OversizePackets:         rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_Packets64Octets:         rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_Packets65To127Octets:    rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_Packets128To255Octets:   rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_Packets256To511Octets:   rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_Packets512To1023Octets:  rand.Intn(100),
			me.EthernetFramePerformanceMonitoringHistoryDataDownstream_Packets1024To1518Octets: rand.Intn(100),
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewEthernetFramePerformanceMonitoringHistoryDataDownstream %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.EthernetFramePerformanceMonitoringHistoryDataDownstreamClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createEthernetPerformanceMonitoringHistoryDataResponse(isExtended bool, attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewEthernetPerformanceMonitoringHistoryData(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID: entityID,
			me.EthernetPerformanceMonitoringHistoryData_IntervalEndTime:                 0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			me.EthernetPerformanceMonitoringHistoryData_ThresholdData12Id:               0,
			me.EthernetPerformanceMonitoringHistoryData_FcsErrors:                       rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_ExcessiveCollisionCounter:       rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_LateCollisionCounter:            rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_FramesTooLong:                   rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_BufferOverflowsOnReceive:        rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_BufferOverflowsOnTransmit:       rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_SingleCollisionFrameCounter:     rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_MultipleCollisionsFrameCounter:  rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_SqeCounter:                      rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_DeferredTransmissionCounter:     rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_InternalMacTransmitErrorCounter: rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_CarrierSenseErrorCounter:        rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_AlignmentErrorCounter:           rand.Intn(100),
			me.EthernetPerformanceMonitoringHistoryData_InternalMacReceiveErrorCounter:  rand.Intn(100),
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewEthernetPerformanceMonitoringHistoryData %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.EthernetPerformanceMonitoringHistoryDataClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createFecPerformanceMonitoringHistoryDataResponse(isExtended bool, attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewFecPerformanceMonitoringHistoryData(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID: entityID,
			me.FecPerformanceMonitoringHistoryData_IntervalEndTime:        0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			me.FecPerformanceMonitoringHistoryData_ThresholdData12Id:      0,
			me.FecPerformanceMonitoringHistoryData_CorrectedBytes:         rand.Intn(100),
			me.FecPerformanceMonitoringHistoryData_CorrectedCodeWords:     rand.Intn(100),
			me.FecPerformanceMonitoringHistoryData_UncorrectableCodeWords: rand.Intn(100),
			me.FecPerformanceMonitoringHistoryData_TotalCodeWords:         rand.Intn(100),
			me.FecPerformanceMonitoringHistoryData_FecSeconds:             rand.Intn(100),
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewFecPerformanceMonitoringHistoryData %v", meErr.Error())
		return nil
	}

	// FEC History counter fits within single gem payload.
	// No need of the logical we use in other Ethernet History counters or Gem Port History counters

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.FecPerformanceMonitoringHistoryDataClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createGemPortNetworkCtpPerformanceMonitoringHistoryData(isExtended bool, attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewGemPortNetworkCtpPerformanceMonitoringHistoryData(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID: entityID,
			me.GemPortNetworkCtpPerformanceMonitoringHistoryData_IntervalEndTime:         0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			me.GemPortNetworkCtpPerformanceMonitoringHistoryData_ThresholdData12Id:       0,
			me.GemPortNetworkCtpPerformanceMonitoringHistoryData_TransmittedGemFrames:    rand.Intn(100),
			me.GemPortNetworkCtpPerformanceMonitoringHistoryData_ReceivedGemFrames:       rand.Intn(100),
			me.GemPortNetworkCtpPerformanceMonitoringHistoryData_ReceivedPayloadBytes:    rand.Intn(100),
			me.GemPortNetworkCtpPerformanceMonitoringHistoryData_TransmittedPayloadBytes: rand.Intn(100),
			me.GemPortNetworkCtpPerformanceMonitoringHistoryData_EncryptionKeyErrors:     rand.Intn(100),
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewGemPortNetworkCtpPerformanceMonitoringHistoryData %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createOnuDataResponse(isExtended bool, attributeMask uint16, entityID uint16, mds uint8) *omci.GetResponse {
	managedEntity, meErr := me.NewOnuData(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID:     entityID,
			me.OnuData_MibDataSync: mds,
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewOnuData %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.OnuDataClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createAnigResponse(isExtended bool, attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewAniG(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			me.ManagedEntityID:                  entityID,
			me.AniG_SrIndication:                0,
			me.AniG_TotalTcontNumber:            0,
			me.AniG_GemBlockLength:              0,
			me.AniG_PiggybackDbaReporting:       0,
			me.AniG_Deprecated:                  0,
			me.AniG_SignalFailThreshold:         0,
			me.AniG_SignalDegradeThreshold:      0,
			me.AniG_Arc:                         0,
			me.AniG_ArcInterval:                 0,
			me.AniG_OpticalSignalLevel:          rand.Intn(16000), // generate some random power level than defaulting to 0
			me.AniG_LowerOpticalThreshold:       0,
			me.AniG_UpperOpticalThreshold:       0,
			me.AniG_OnuResponseTime:             0,
			me.AniG_TransmitOpticalLevel:        rand.Intn(16000), // generate some random power level than defaulting to 0
			me.AniG_LowerTransmitPowerThreshold: 0,
			me.AniG_UpperTransmitPowerThreshold: 0,
		},
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewAniG %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.AniGClassID,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createEthernetFrameExtendedPmGetResponse(isExtended bool, meClass me.ClassID, attributeMask uint16, entityID uint16) *omci.GetResponse {

	callback := me.NewEthernetFrameExtendedPm
	if meClass != me.EthernetFrameExtendedPmClassID {
		callback = me.NewEthernetFrameExtendedPm64Bit
	}

	//The names of these attributes are left as strings
	//rather than constants of a particular ME because
	//they can be used with both the MEs in the lines above
	attr := me.AttributeValueMap{
		me.ManagedEntityID:       entityID,
		"DropEvents":             100,
		"Octets":                 101,
		"Frames":                 102,
		"BroadcastFrames":        103,
		"MulticastFrames":        104,
		"CrcErroredFrames":       105,
		"UndersizeFrames":        106,
		"OversizeFrames":         107,
		"Frames64Octets":         108,
		"Frames65To127Octets":    109,
		"Frames128To255Octets":   110,
		"Frames256To511Octets":   111,
		"Frames512To1023Octets":  112,
		"Frames1024To1518Octets": 113,
	}
	managedEntity, meErr := callback(me.ParamData{
		EntityID:   entityID,
		Attributes: attr,
	})

	if meErr.GetError() != nil {
		omciLogger.Errorf("NewEthernetFrameExtendedPm %v", meErr.Error())
		return nil
	}

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    meClass,
			EntityInstance: entityID,
			Extended:       isExtended,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func ToOctets(str string, size int) []byte {
	asciiBytes := []byte(str)

	if len(asciiBytes) < size {
		missing := size - len(asciiBytes)
		for i := 0; i < missing; i++ {
			asciiBytes = append(asciiBytes, []byte{0x00}[0])
		}
	}
	return asciiBytes
}
