/*
 * 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"
	"github.com/google/gopacket"
	"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"
	"math/rand"
	"strconv"
)

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{
		"EntityClass":    msgObj.EntityClass,
		"EntityInstance": msgObj.EntityInstance,
		"AttributeMask":  fmt.Sprintf("%x", msgObj.AttributeMask),
	}).Trace("received-omci-get-request")

	var response *omci.GetResponse
	switch msgObj.EntityClass {
	case me.Onu2GClassID:
		response = createOnu2gResponse(msgObj.AttributeMask, msgObj.EntityInstance)
	case me.OnuGClassID:
		response = createOnugResponse(msgObj.AttributeMask, msgObj.EntityInstance, onuSn)
	case me.SoftwareImageClassID:
		response = createSoftwareImageResponse(msgObj.AttributeMask, msgObj.EntityInstance,
			activeImageEntityId, committedImageEntityId, standbyImageVersion, activeImageVersion, committedImageVersion)
	case me.IpHostConfigDataClassID:
		response = createIpHostResponse(msgObj.AttributeMask, msgObj.EntityInstance)
	case me.UniGClassID:
		response = createUnigResponse(msgObj.AttributeMask, msgObj.EntityInstance, onuDown)
	case me.PhysicalPathTerminationPointEthernetUniClassID:
		response = createPptpResponse(msgObj.AttributeMask, msgObj.EntityInstance, onuDown)
	case me.AniGClassID:
		response = createAnigResponse(msgObj.AttributeMask, msgObj.EntityInstance)
	case me.OnuDataClassID:
		response = createOnuDataResponse(msgObj.AttributeMask, msgObj.EntityInstance, mds)
	case me.EthernetFramePerformanceMonitoringHistoryDataUpstreamClassID:
		response = createEthernetFramePerformanceMonitoringHistoryDataUpstreamResponse(msgObj.AttributeMask, msgObj.EntityInstance)
	case me.EthernetFramePerformanceMonitoringHistoryDataDownstreamClassID:
		response = createEthernetFramePerformanceMonitoringHistoryDataDownstreamResponse(msgObj.AttributeMask, msgObj.EntityInstance)
	case me.EthernetPerformanceMonitoringHistoryDataClassID:
		response = createEthernetPerformanceMonitoringHistoryDataResponse(msgObj.AttributeMask, msgObj.EntityInstance)
	case me.FecPerformanceMonitoringHistoryDataClassID:
		response = createFecPerformanceMonitoringHistoryDataResponse(msgObj.AttributeMask, msgObj.EntityInstance)
	case me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID:
		response = createGemPortNetworkCtpPerformanceMonitoringHistoryData(msgObj.AttributeMask, msgObj.EntityInstance)
	case me.EthernetFrameExtendedPmClassID,
		me.EthernetFrameExtendedPm64BitClassID:
		response = createEthernetFrameExtendedPmGetResponse(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
	}

	pkt, err := Serialize(omci.GetResponseType, response, omciMsg.TransactionID)
	if err != nil {
		omciLogger.WithFields(log.Fields{
			"Err":  err,
			"TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
		}).Error("cannot-Serialize-GetResponse")
		return nil, err
	}

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

	return pkt, nil
}

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

	managedEntity, meErr := me.NewOnu2G(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId": entityID,
			"EquipmentId":     ToOctets("12345123451234512345", 20),
			"OpticalNetworkUnitManagementAndControlChannelOmccVersion": 180,
			"VendorProductCode":                           0,
			"SecurityCapability":                          1,
			"SecurityMode":                                1,
			"TotalPriorityQueueNumber":                    1,
			"TotalTrafficSchedulerNumber":                 1,
			"Deprecated":                                  1,
			"TotalGemPortIdNumber":                        32,
			"Sysuptime":                                   319389947, // NOTE need to be smarter?
			"ConnectivityCapability":                      127,
			"CurrentConnectivityMode":                     5,
			"QualityOfServiceQosConfigurationFlexibility": 48,
			"PriorityQueueScaleFactor":                    1,
		},
	})

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

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

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

	managedEntity, meErr := me.NewOnuG(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId":         entityID,
			"VendorId":                ToOctets("BBSM", 4),
			"Version":                 ToOctets("v0.0.1", 14),
			"SerialNumber":            append(onuSn.VendorId, onuSn.VendorSpecific...),
			"TrafficManagementOption": 0,
			"Deprecated":              0,
			"BatteryBackup":           0,
			"AdministrativeState":     0,
			"OperationalState":        0,
			"OnuSurvivalTime":         10,
			"LogicalOnuId":            ToOctets("BBSM", 24),
			"LogicalPassword":         ToOctets("BBSM", 12),
			"CredentialsStatus":       0,
			"ExtendedTcLayerOptions":  0,
		},
	})

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

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

	//return &omci.GetResponse{
	//	MeBasePacket: omci.MeBasePacket{
	//		EntityClass:    me.OnuGClassID,
	//		EntityInstance: entityID,
	//	},
	//	Attributes: me.AttributeValueMap{
	//
	//	},
	//	Result:        me.Success,
	//	AttributeMask: attributeMask,
	//}
}

func createSoftwareImageResponse(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,
		},
		Attributes: me.AttributeValueMap{
			"ManagedEntityId": 0,
			"Version":         ToOctets(version, 14),
			"IsCommitted":     committed,
			"IsActive":        active,
			"IsValid":         1,
			"ProductCode":     ToOctets("BBSIM-ONU", 25),
			"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(attributeMask uint16, entityInstance uint16) *omci.GetResponse {
	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    me.IpHostConfigDataClassID,
			EntityInstance: entityInstance,
		},
		Attributes: me.AttributeValueMap{
			"ManagedEntityId": 0,
			"MacAddress":      ToOctets("aabbcc", 6),
		},
		Result:        me.Success,
		AttributeMask: attributeMask,
	}
}

func createUnigResponse(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{
			"ManagedEntityId":             entityID,
			"Deprecated":                  0,
			"AdministrativeState":         omciAdminState,
			"ManagementCapability":        0,
			"NonOmciManagementIdentifier": 1,
			"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,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createPptpResponse(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{
			"ManagedEntityId":               entityID,
			"ExpectedType":                  0,
			"SensedType":                    0,
			"AutoDetectionConfiguration":    0,
			"EthernetLoopbackConfiguration": 0,
			"AdministrativeState":           onuAdminState,
			"OperationalState":              onuOperState,
			"ConfigurationInd":              0,
			"MaxFrameSize":                  0,
			"DteOrDceInd":                   0,
			"PauseTime":                     0,
			"BridgedOrIpInd":                0,
			"Arc":                           0,
			"ArcInterval":                   0,
			"PppoeFilter":                   0,
			"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,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createEthernetFramePerformanceMonitoringHistoryDataUpstreamResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewEthernetFramePerformanceMonitoringHistoryDataUpstream(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId":         entityID,
			"IntervalEndTime":         0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			"ThresholdData12Id":       0,
			"DropEvents":              rand.Intn(100),
			"Octets":                  rand.Intn(100),
			"Packets":                 rand.Intn(100),
			"BroadcastPackets":        rand.Intn(100),
			"MulticastPackets":        rand.Intn(100),
			"CrcErroredPackets":       rand.Intn(100),
			"UndersizePackets":        rand.Intn(100),
			"OversizePackets":         rand.Intn(100),
			"Packets64Octets":         rand.Intn(100),
			"Packets65To127Octets":    rand.Intn(100),
			"Packets128To255Octets":   rand.Intn(100),
			"Packets256To511Octets":   rand.Intn(100),
			"Packets512To1023Octets":  rand.Intn(100),
			"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,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createEthernetFramePerformanceMonitoringHistoryDataDownstreamResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewEthernetFramePerformanceMonitoringHistoryDataDownstream(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId":         entityID,
			"IntervalEndTime":         0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			"ThresholdData12Id":       0,
			"DropEvents":              rand.Intn(100),
			"Octets":                  rand.Intn(100),
			"Packets":                 rand.Intn(100),
			"BroadcastPackets":        rand.Intn(100),
			"MulticastPackets":        rand.Intn(100),
			"CrcErroredPackets":       rand.Intn(100),
			"UndersizePackets":        rand.Intn(100),
			"OversizePackets":         rand.Intn(100),
			"Packets64Octets":         rand.Intn(100),
			"Packets65To127Octets":    rand.Intn(100),
			"Packets128To255Octets":   rand.Intn(100),
			"Packets256To511Octets":   rand.Intn(100),
			"Packets512To1023Octets":  rand.Intn(100),
			"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,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createEthernetPerformanceMonitoringHistoryDataResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewEthernetPerformanceMonitoringHistoryData(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId":                 entityID,
			"IntervalEndTime":                 0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			"ThresholdData12Id":               0,
			"FcsErrors":                       rand.Intn(100),
			"ExcessiveCollisionCounter":       rand.Intn(100),
			"LateCollisionCounter":            rand.Intn(100),
			"FramesTooLong":                   rand.Intn(100),
			"BufferOverflowsOnReceive":        rand.Intn(100),
			"BufferOverflowsOnTransmit":       rand.Intn(100),
			"SingleCollisionFrameCounter":     rand.Intn(100),
			"MultipleCollisionsFrameCounter":  rand.Intn(100),
			"SqeCounter":                      rand.Intn(100),
			"DeferredTransmissionCounter":     rand.Intn(100),
			"InternalMacTransmitErrorCounter": rand.Intn(100),
			"CarrierSenseErrorCounter":        rand.Intn(100),
			"AlignmentErrorCounter":           rand.Intn(100),
			"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,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createFecPerformanceMonitoringHistoryDataResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewFecPerformanceMonitoringHistoryData(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId":        entityID,
			"IntervalEndTime":        0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			"ThresholdData12Id":      0,
			"CorrectedBytes":         rand.Intn(100),
			"CorrectedCodeWords":     rand.Intn(100),
			"UncorrectableCodeWords": rand.Intn(100),
			"TotalCodeWords":         rand.Intn(100),
			"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,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createGemPortNetworkCtpPerformanceMonitoringHistoryData(attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewGemPortNetworkCtpPerformanceMonitoringHistoryData(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId":         entityID,
			"IntervalEndTime":         0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
			"ThresholdData12Id":       0,
			"TransmittedGemFrames":    rand.Intn(100),
			"ReceivedGemFrames":       rand.Intn(100),
			"ReceivedPayloadBytes":    rand.Intn(100),
			"TransmittedPayloadBytes": rand.Intn(100),
			"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,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createOnuDataResponse(attributeMask uint16, entityID uint16, mds uint8) *omci.GetResponse {
	managedEntity, meErr := me.NewOnuData(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId": entityID,
			"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,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

func createAnigResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
	managedEntity, meErr := me.NewAniG(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId":             entityID,
			"SrIndication":                0,
			"TotalTcontNumber":            0,
			"GemBlockLength":              0,
			"PiggybackDbaReporting":       0,
			"Deprecated":                  0,
			"SignalFailThreshold":         0,
			"SignalDegradeThreshold":      0,
			"Arc":                         0,
			"ArcInterval":                 0,
			"OpticalSignalLevel":          rand.Intn(16000), // generate some random power level than defaulting to 0
			"LowerOpticalThreshold":       0,
			"UpperOpticalThreshold":       0,
			"OnuResponseTime":             0,
			"TransmitOpticalLevel":        rand.Intn(16000), // generate some random power level than defaulting to 0
			"LowerTransmitPowerThreshold": 0,
			"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,
		},
		Attributes:    managedEntity.GetAttributeValueMap(),
		AttributeMask: attributeMask,
		Result:        me.Success,
	}
}

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

	callback := me.NewEthernetFrameExtendedPm
	if meClass != me.EthernetFrameExtendedPmClassID {
		callback = me.NewEthernetFrameExtendedPm64Bit
	}
	managedEntity, meErr := callback(me.ParamData{
		EntityID: entityID,
		Attributes: me.AttributeValueMap{
			"ManagedEntityId":        entityID,
			"DropEvents":             rand.Intn(100),
			"Octets":                 rand.Intn(100),
			"Frames":                 rand.Intn(100),
			"BroadcastFrames":        rand.Intn(100),
			"MulticastFrames":        rand.Intn(100),
			"CrcErroredFrames":       rand.Intn(100),
			"UndersizeFrames":        rand.Intn(100),
			"OversizeFrames":         rand.Intn(100),
			"Frames64Octets":         rand.Intn(100),
			"Frames65To127Octets":    rand.Intn(100),
			"Frames128To255Octets":   rand.Intn(100),
			"Frames256To511Octets":   rand.Intn(100),
			"Frames512To1023Octets":  rand.Intn(100),
			"Frames1024To1518Octets": rand.Intn(100),
		},
	})

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

	return &omci.GetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass:    meClass,
			EntityInstance: entityID,
		},
		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
}
