/*
 * 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 (
	"errors"
	"github.com/google/gopacket"
	"github.com/opencord/omci-lib-go"
	me "github.com/opencord/omci-lib-go/generated"
	log "github.com/sirupsen/logrus"
)

var omciLogger = log.WithFields(log.Fields{
	"module": "OMCI",
})

const galEthernetEID = uint16(1)
const maxGemPayloadSize = uint16(48)
const gemEID = uint16(1)

type txFrameCreator func() ([]byte, error)
type rxFrameParser func(gopacket.Packet) error

type ServiceStep struct {
	MakeTxFrame txFrameCreator
	RxHandler   rxFrameParser
}

// NOTE this is basically the same as https://github.com/opencord/voltha-openonu-adapter-go/blob/master/internal/pkg/onuadaptercore/omci_cc.go#L545-L564
// we should probably move it in "omci-lib-go"
func Serialize(msgType omci.MessageType, request gopacket.SerializableLayer, tid uint16) ([]byte, error) {
	omciLayer := &omci.OMCI{
		TransactionID: tid,
		MessageType:   msgType,
	}
	var options gopacket.SerializeOptions
	options.FixLengths = true

	buffer := gopacket.NewSerializeBuffer()
	err := gopacket.SerializeLayers(buffer, options, omciLayer, request)
	if err != nil {
		return nil, err
	}
	return buffer.Bytes(), nil
}

func CreateMibResetRequest(tid uint16) ([]byte, error) {

	request := &omci.MibResetRequest{
		MeBasePacket: omci.MeBasePacket{
			EntityClass: me.OnuDataClassID,
		},
	}
	pkt, err := Serialize(omci.MibResetRequestType, request, tid)
	if err != nil {
		omciLogger.WithFields(log.Fields{
			"Err": err,
		}).Fatalf("Cannot Serialize MibResetRequest")
		return nil, err
	}
	return HexEncode(pkt)
}

func CreateMibResetResponse(tid uint16) ([]byte, error) {

	request := &omci.MibResetResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass: me.OnuDataClassID,
		},
		Result: me.Success,
	}
	pkt, err := Serialize(omci.MibResetResponseType, request, tid)
	if err != nil {
		omciLogger.WithFields(log.Fields{
			"Err": err,
		}).Error("Cannot Serialize MibResetResponse")
		return nil, err
	}
	return pkt, nil
}

func CreateMibUploadRequest(tid uint16) ([]byte, error) {
	request := &omci.MibUploadRequest{
		MeBasePacket: omci.MeBasePacket{
			EntityClass: me.OnuDataClassID,
			// Default Instance ID is 0
		},
	}
	pkt, err := Serialize(omci.MibUploadRequestType, request, tid)
	if err != nil {
		omciLogger.WithFields(log.Fields{
			"Err": err,
		}).Fatalf("Cannot Serialize MibUploadRequest")
		return nil, err
	}
	return HexEncode(pkt)
}

func CreateMibUploadResponse(tid uint16) ([]byte, error) {

	numberOfCommands := uint16(291) //NOTE should this be configurable? (not until we have moved all the messages away from omci-sim)

	request := &omci.MibUploadResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass: me.OnuDataClassID,
		},
		NumberOfCommands: numberOfCommands,
	}
	pkt, err := Serialize(omci.MibUploadResponseType, request, tid)
	if err != nil {
		omciLogger.WithFields(log.Fields{
			"Err": err,
		}).Error("Cannot Serialize MibUploadResponse")
		return nil, err
	}
	return pkt, nil
}

func CreateMibUploadNextRequest(tid uint16, seqNumber uint16) ([]byte, error) {

	request := &omci.MibUploadNextRequest{
		MeBasePacket: omci.MeBasePacket{
			EntityClass: me.OnuDataClassID,
			// Default Instance ID is 0
		},
		CommandSequenceNumber: seqNumber,
	}
	pkt, err := Serialize(omci.MibUploadNextRequestType, request, tid)

	if err != nil {
		omciLogger.WithFields(log.Fields{
			"Err": err,
		}).Fatalf("Cannot Serialize MibUploadNextRequest")
		return nil, err
	}
	return HexEncode(pkt)
}

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

func CreateMibUploadNextResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI, mds uint8) ([]byte, error) {

	msgObj, err := ParseMibUploadNextRequest(omciPkt)
	if err != nil {
		err := "omci Msg layer could not be assigned for LayerTypeGetRequest"
		omciLogger.Error(err)
		return nil, errors.New(err)
	}

	omciLogger.WithFields(log.Fields{
		"EntityClass":           msgObj.EntityClass,
		"EntityInstance":        msgObj.EntityInstance,
		"CommandSequenceNumber": msgObj.CommandSequenceNumber,
	}).Trace("received-omci-mibUploadNext-request")

	// depending on the sequenceNumber we'll report a different
	reportedMe := &me.ManagedEntity{}
	var meErr me.OmciErrors
	//var entityInstance uint16
	switch msgObj.CommandSequenceNumber {
	case 0:
		reportedMe, meErr = me.NewOnuData(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId": me.OnuDataClassID,
			"MibDataSync":     mds,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewOnuData %v", meErr.Error())
		}

	case 1:
		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId": me.CircuitPackClassID,
			"Type":            47,
			"NumberOfPorts":   4,
			"SerialNumber":    toOctets("BBSM-Circuit-Pack", 20),
			"Version":         toOctets("v0.0.1", 20),
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
		}
	case 2:
		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":     me.CircuitPackClassID,
			"VendorId":            "ONF",
			"AdministrativeState": 0,
			"OperationalState":    0,
			"BridgedOrIpInd":      0,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
		}
	case 3:
		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":             me.CircuitPackClassID,
			"EquipmentId":                 toOctets("BBSM-Circuit-Pack", 20),
			"CardConfiguration":           0,
			"TotalTContBufferNumber":      0,
			"TotalPriorityQueueNumber":    8,
			"TotalTrafficSchedulerNumber": 0,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
		}
	case 4:
		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":   me.CircuitPackClassID,
			"PowerShedOverride": uint32(0),
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
		}
	case 5:
		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId": me.CircuitPackClassID,
			"Type":            238,
			"NumberOfPorts":   1,
			"SerialNumber":    toOctets("BBSM-Circuit-Pack-2", 20),
			"Version":         toOctets("v0.0.1", 20),
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
		}
	case 6:
		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":     me.CircuitPackClassID,
			"VendorId":            "ONF",
			"AdministrativeState": 0,
			"OperationalState":    0,
			"BridgedOrIpInd":      0,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
		}
	case 7:
		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":             me.CircuitPackClassID,
			"EquipmentId":                 toOctets("BBSM-Circuit-Pack", 20),
			"CardConfiguration":           0,
			"TotalTContBufferNumber":      8,
			"TotalPriorityQueueNumber":    40,
			"TotalTrafficSchedulerNumber": 10,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
		}
	case 8:
		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":   me.CircuitPackClassID,
			"PowerShedOverride": uint32(0),
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
		}
	case 9, 10, 11, 12:
		// NOTE we're reporting for different UNIs, the IDs are 257, 258, 259, 260
		meInstance := 248 + msgObj.CommandSequenceNumber
		reportedMe, meErr = me.NewPhysicalPathTerminationPointEthernetUni(me.ParamData{
			EntityID: meInstance,
			Attributes: me.AttributeValueMap{
				"ExpectedType":                  0,
				"SensedType":                    47,
				"AutoDetectionConfiguration":    0,
				"EthernetLoopbackConfiguration": 0,
				"AdministrativeState":           0,
				"OperationalState":              0,
				"ConfigurationInd":              3,
				"MaxFrameSize":                  1518,
				"DteOrDceInd":                   0,
				"PauseTime":                     0,
				"BridgedOrIpInd":                2,
				"Arc":                           0,
				"ArcInterval":                   0,
				"PppoeFilter":                   0,
				"PowerControl":                  0,
			}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewPhysicalPathTerminationPointEthernetUni %v", meErr.Error())
		}
	case 13, 14, 15, 16, 17, 18, 19, 20:
		// TODO report different MeID (see omci-sim pcap filter "frame[22:2] == 01:06")
		reportedMe, meErr = me.NewTCont(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId": me.TContClassID,
			"AllocId":         0,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewTCont %v", meErr.Error())
		}
	case 21:
		reportedMe, meErr = me.NewAniG(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":             me.AniGClassID,
			"SrIndication":                1,
			"TotalTcontNumber":            8,
			"GemBlockLength":              30,
			"PiggybackDbaReporting":       0,
			"Deprecated":                  0,
			"SignalFailThreshold":         5,
			"SignalDegradeThreshold":      9,
			"Arc":                         0,
			"ArcInterval":                 0,
			"OpticalSignalLevel":          57428,
			"LowerOpticalThreshold":       255,
			"UpperOpticalThreshold":       255,
			"OnuResponseTime":             0,
			"TransmitOpticalLevel":        3171,
			"LowerTransmitPowerThreshold": 129,
			"UpperTransmitPowerThreshold": 129,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewAniG %v", meErr.Error())
		}
	case 22, 23, 24, 25:
		// TODO report different MeID (see omci-sim pcap filter "frame[22:2] == 01:08")
		reportedMe, meErr = me.NewUniG(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":     me.UniGClassID,
			"Deprecated":          0,
			"AdministrativeState": 0,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewUniG %v", meErr.Error())
		}
	case 26, 30, 34, 38, 42, 46, 50, 54,
		58, 62, 66, 70, 74, 78, 82, 86,
		90, 94, 98, 102, 106, 110, 114, 118,
		122, 126, 130, 134, 138, 142, 146, 150,
		154, 158, 162, 166, 170, 174, 178, 182,
		186, 190, 194, 198, 202, 206, 210, 214,
		218, 222, 226, 230, 234, 238, 242, 246,
		250, 254, 258, 262, 266, 270, 274, 278:
	case 27, 31, 35, 39, 43, 47, 51, 55,
		59, 63, 67, 71, 75, 79, 83, 87,
		91, 95, 99, 103, 107, 111, 115, 119,
		123, 127, 131, 135, 139, 143, 147, 151,
		155, 159, 163, 167, 171, 175, 179, 183,
		187, 191, 195, 199, 203, 207, 211, 215,
		219, 223, 227, 231, 235, 239, 243, 247,
		251, 255, 259, 263, 267, 271, 275, 279:
	case 28, 32, 36, 40, 44, 48, 52, 56,
		60, 64, 68, 72, 76, 80, 84, 88,
		92, 96, 100, 104, 108, 112, 116, 120,
		124, 128, 132, 136, 140, 144, 148, 152,
		156, 160, 164, 168, 172, 176, 180, 184,
		188, 192, 196, 200, 204, 208, 212, 216,
		220, 224, 228, 232, 236, 240, 244, 248,
		252, 256, 260, 264, 268, 272, 276, 280:
	case 29, 33, 37, 41, 45, 49, 53, 57,
		61, 65, 69, 73, 77, 81, 85, 89,
		93, 97, 101, 105, 109, 113, 117, 121,
		125, 129, 133, 137, 141, 145, 149, 153,
		157, 161, 165, 169, 173, 177, 181, 185,
		189, 193, 197, 201, 205, 209, 213, 217,
		221, 225, 229, 233, 237, 241, 245, 249,
		253, 257, 261, 265, 269, 273, 277, 281:
		reportedMe, meErr = me.NewPriorityQueue(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":                                     me.PriorityQueueClassID,
			"QueueConfigurationOption":                            0,
			"MaximumQueueSize":                                    100,
			"AllocatedQueueSize":                                  100,
			"DiscardBlockCounterResetInterval":                    0,
			"ThresholdValueForDiscardedBlocksDueToBufferOverflow": 0,
			"RelatedPort":                                         80010000, // does this need to change?
			"TrafficSchedulerPointer":                             8008,     // does this need to change?
			"Weight":                                              1,
			"BackPressureOperation":                               1,
			"BackPressureTime":                                    0,
			"BackPressureOccurQueueThreshold":                     0,
			"BackPressureClearQueueThreshold":                     0,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewPriorityQueue %v", meErr.Error())
		}
	case 282, 283, 284, 285, 286, 287, 288, 289:
		reportedMe, meErr = me.NewTrafficScheduler(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":         me.TrafficSchedulerClassID,
			"TContPointer":            8008, // NOTE does this need to change?
			"TrafficSchedulerPointer": 0,
			"Policy":                  02,
			"PriorityWeight":          0,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewTrafficScheduler %v", meErr.Error())
		}
	case 290:
		reportedMe, meErr = me.NewOnu2G(me.ParamData{Attributes: me.AttributeValueMap{
			"ManagedEntityId":             me.Onu2GClassID,
			"TotalPriorityQueueNumber":    40,
			"SecurityMode":                1,
			"TotalTrafficSchedulerNumber": 8,
			"TotalGemPortIdNumber":        0,
			"Sysuptime":                   0,
		}})
		if meErr.GetError() != nil {
			omciLogger.Errorf("NewOnu2G %v", meErr.Error())
		}
	default:
		omciLogger.Warn("unsupported-CommandSequenceNumber-in-mib-upload-next", msgObj.CommandSequenceNumber)
		return nil, nil
	}

	response := &omci.MibUploadNextResponse{
		MeBasePacket: omci.MeBasePacket{
			EntityClass: me.OnuDataClassID,
		},
		ReportedME: *reportedMe,
	}

	omciLogger.WithFields(log.Fields{
		"reportedMe": reportedMe,
	}).Trace("created-omci-mibUploadNext-response")

	pkt, err := Serialize(omci.MibUploadNextResponseType, response, omciMsg.TransactionID)

	if err != nil {
		omciLogger.WithFields(log.Fields{
			"Err": err,
		}).Fatalf("Cannot Serialize MibUploadNextRequest")
		return nil, err
	}

	return pkt, nil
}
