/*
 * 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"
	"fmt"
	"github.com/google/gopacket"
	"github.com/opencord/omci-lib-go"
	me "github.com/opencord/omci-lib-go/generated"
	"github.com/opencord/voltha-protos/v4/go/openolt"
	"gotest.tools/assert"
	"testing"
)

func omciBytesToMsg(t *testing.T, data []byte) (*omci.OMCI, *gopacket.Packet) {
	packet := gopacket.NewPacket(data, omci.LayerTypeOMCI, gopacket.NoCopy)
	if packet == nil {
		t.Fatal("could not decode rxMsg as OMCI")
	}
	omciLayer := packet.Layer(omci.LayerTypeOMCI)
	if omciLayer == nil {
		t.Fatal("could not decode omci layer")
	}
	omciMsg, ok := omciLayer.(*omci.OMCI)
	if !ok {
		t.Fatal("could not assign omci layer")
	}
	return omciMsg, &packet
}

func omciToGetResponse(t *testing.T, omciPkt *gopacket.Packet) *omci.GetResponse {
	msgLayer := (*omciPkt).Layer(omci.LayerTypeGetResponse)
	if msgLayer == nil {
		t.Fatal("omci Msg layer could not be detected for GetResponse - handling of MibSyncChan stopped")
	}
	msgObj, msgOk := msgLayer.(*omci.GetResponse)
	if !msgOk {
		t.Fatal("omci Msg layer could not be assigned for GetResponse - handling of MibSyncChan stopped")
	}
	return msgObj
}

type getArgs struct {
	generatedPkt  *omci.GetResponse
	transactionId uint16
}

type getWant struct {
	transactionId uint16
	attributes    map[string]interface{}
}

func TestGetResponse(t *testing.T) {

	// NOTE that we're not testing the SerialNumber attribute part of the ONU-G
	// response here as it is a special case and it requires transformation.
	// we specifically test that in TestCreateOnugResponse
	sn := &openolt.SerialNumber{
		VendorId:       []byte("BBSM"),
		VendorSpecific: []byte{0, byte(1 % 256), byte(1), byte(1)},
	}

	tests := []struct {
		name string
		args getArgs
		want getWant
	}{
		{"getOnu2gResponse",
			getArgs{createOnu2gResponse(57344, 10), 1},
			getWant{1, map[string]interface{}{"OpticalNetworkUnitManagementAndControlChannelOmccVersion": uint8(180)}},
		},
		{"getOnugResponse",
			getArgs{createOnugResponse(40960, 10, sn), 1},
			getWant{1, map[string]interface{}{}},
		},
		{"getOnuDataResponse",
			getArgs{createOnuDataResponse(32768, 10, 129), 2},
			getWant{2, map[string]interface{}{"MibDataSync": uint8(129)}},
		},
		{"getGemPortNetworkCtpPerformanceMonitoringHistoryDataResponse",
			getArgs{createGemPortNetworkCtpPerformanceMonitoringHistoryData(32768, 10), 2},
			getWant{2, map[string]interface{}{"ManagedEntityId": uint16(10)}},
		},
		{"getEthernetFramePerformanceMonitoringHistoryDataUpstreamResponse",
			getArgs{createEthernetFramePerformanceMonitoringHistoryDataUpstreamResponse(32768, 10), 2},
			getWant{2, map[string]interface{}{"ManagedEntityId": uint16(10)}},
		},
		{"getEthernetFramePerformanceMonitoringHistoryDataDownstreamResponse",
			getArgs{createEthernetFramePerformanceMonitoringHistoryDataDownstreamResponse(32768, 10), 2},
			getWant{2, map[string]interface{}{"ManagedEntityId": uint16(10)}},
		},
		{"getEthernetPerformanceMonitoringHistoryDataResponse",
			getArgs{createEthernetPerformanceMonitoringHistoryDataResponse(32768, 10), 2},
			getWant{2, map[string]interface{}{"ManagedEntityId": uint16(10)}},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {

			data, err := Serialize(omci.GetResponseType, tt.args.generatedPkt, tt.args.transactionId)
			if err != nil {
				t.Fatal("cannot-serial-omci-packet", err)
			}

			// emulate the openonu-go behavior:
			// omci_cc.receiveMessage process the message (creates a gopacket and extracts the OMCI layer) and invokes a callback
			// in the GetResponse case omci_cc.receiveOmciResponse
			// then the OmciMessage (gopacket + OMIC layer) is is published on a channel
			omciMsg, omciPkt := omciBytesToMsg(t, data)

			assert.Equal(t, omciMsg.MessageType, omci.GetResponseType)
			assert.Equal(t, omciMsg.TransactionID, tt.want.transactionId)

			// that is read by myb_sync.processMibSyncMessages
			// the myb_sync.handleOmciMessage is called and then
			// myb_sync.handleOmciGetResponseMessage where we extract the GetResponse layer
			getResponseLayer := omciToGetResponse(t, omciPkt)

			assert.Equal(t, getResponseLayer.Result, me.Success)

			for k, v := range tt.want.attributes {
				attr := getResponseLayer.Attributes[k]
				assert.Equal(t, attr, v)
			}
		})
	}
}

func TestCreateOnugResponse(t *testing.T) {

	sn := &openolt.SerialNumber{
		VendorId:       []byte("BBSM"),
		VendorSpecific: []byte{0, byte(1 % 256), byte(1), byte(1)},
	}
	response := createOnugResponse(40960, 1, sn)
	data, _ := Serialize(omci.GetResponseType, response, 1)

	omciMsg, omciPkt := omciBytesToMsg(t, data)

	assert.Equal(t, omciMsg.MessageType, omci.GetResponseType)

	getResponseLayer := omciToGetResponse(t, omciPkt)

	assert.Equal(t, getResponseLayer.Result, me.Success)
	snBytes := (getResponseLayer.Attributes["SerialNumber"]).([]byte)
	snVendorPart := fmt.Sprintf("%s", snBytes[:4])
	snNumberPart := hex.EncodeToString(snBytes[4:])
	serialNumber := snVendorPart + snNumberPart
	assert.Equal(t, serialNumber, "BBSM00010101")
}
