/*
 * 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 (
	"fmt"
	"testing"

	"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/stretchr/testify/assert"
)

func TestEntityID_ToUint16(t *testing.T) {
	var id EntityID
	var res uint16

	id = EntityID{0x01, 0x01}
	res = id.ToUint16()
	assert.Equal(t, uint16(257), res)

	id = EntityID{0x00, 0x00}
	res = id.ToUint16()
	assert.Equal(t, uint16(0), res)
}

func TestEntityID_FromUint16(t *testing.T) {
	id := uint16(257)
	e := EntityID{}.FromUint16(id)

	assert.Equal(t, e.ToString(), "0101")
	assert.Equal(t, e.ToUint16(), id)
}

func TestEntityID_Equals(t *testing.T) {
	a := EntityID{0x01, 0x01}
	b := EntityID{0x01, 0x01}
	c := EntityID{0x01, 0x02}

	assert.True(t, a.Equals(b))
	assert.False(t, a.Equals(c))
}

func Test_GenerateMibDatabase(t *testing.T) {
	common.Config = &common.GlobalConfig{
		BBSim: common.BBSimConfig{
			InjectOmciUnknownAttributes: false,
		},
	}
	const uniPortCount = 4
	mibDb, err := GenerateMibDatabase(uniPortCount, 0, common.XGSPON)

	expectedItems := 9                     //ONU-G + 2 Circuit Packs (4 messages each)
	expectedItems += 2 * uniPortCount      // 1 PPTP and 1 UniG per UNI
	expectedItems += 1                     // ANI-G
	expectedItems += 2 * tconts            // T-CONT and traffic schedulers
	expectedItems += 1                     // ONU-2g
	expectedItems += 2 * 8 * tconts        // 8 upstream queues for each T-CONT, and we report each queue twice
	expectedItems += 2 * 16 * uniPortCount // 16 downstream queues for each T-CONT, and we report each queue twice

	assert.NoError(t, err)
	assert.NotNil(t, mibDb)
	assert.Equal(t, expectedItems, int(mibDb.NumberOfBaselineCommands))

	// now try to serialize all messages to check on the attributes
	for _, entry := range mibDb.baselineItems {
		reportedMe, meErr := me.LoadManagedEntityDefinition(entry.classId, me.ParamData{
			EntityID:   entry.entityId.ToUint16(),
			Attributes: entry.params,
		})
		assert.NoError(t, meErr.GetError())

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

		_, err := Serialize(omci.MibUploadNextResponseType, response, uint16(10))
		assert.NoError(t, err)
	}

}

func Test_GenerateMibDatabase_withPots(t *testing.T) {
	common.Config = &common.GlobalConfig{
		BBSim: common.BBSimConfig{
			InjectOmciUnknownAttributes: false,
		},
	}
	const uniPortCount = 4
	const potsPortCount = 1
	mibDb, err := GenerateMibDatabase(uniPortCount, potsPortCount, common.XGSPON)

	expectedItems := 13                                      //ONU-G + 3 Circuit Packs (4 messages each)
	expectedItems += 2 * (uniPortCount + potsPortCount)      // 1 PPTP and 1 UniG per UNI
	expectedItems += 1                                       // ANI-G
	expectedItems += 2 * tconts                              // T-CONT and traffic schedulers
	expectedItems += 1                                       // ONU-2g
	expectedItems += 2 * 8 * tconts                          // 8 upstream queues for each T-CONT, and we report each queue twice
	expectedItems += 2 * 16 * (uniPortCount + potsPortCount) // 16 downstream queues for each T-CONT, and we report each queue twice

	assert.NoError(t, err)
	assert.NotNil(t, mibDb)
	assert.Equal(t, expectedItems, int(mibDb.NumberOfBaselineCommands))

	// now try to serialize all messages to check on the attributes
	for _, entry := range mibDb.baselineItems {
		reportedMe, meErr := me.LoadManagedEntityDefinition(entry.classId, me.ParamData{
			EntityID:   entry.entityId.ToUint16(),
			Attributes: entry.params,
		})
		assert.NoError(t, meErr.GetError())

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

		_, err := Serialize(omci.MibUploadNextResponseType, response, uint16(10))
		assert.NoError(t, err)
	}

}

func Test_GenerateMibDatabase_withUnkownAttrs(t *testing.T) {

	common.Config = &common.GlobalConfig{
		BBSim: common.BBSimConfig{
			InjectOmciUnknownMe: true,
		},
	}

	const uniPortCount = 4
	const baseMibEntries = 291                    // see Test_GenerateMibDatabase for breakdown
	const expectedMibEntries = baseMibEntries + 1 // expecting one hardcoded packet
	mibDb, err := GenerateMibDatabase(uniPortCount, 0, common.XGSPON)

	assert.NoError(t, err)
	assert.NotNil(t, mibDb)
	assert.Equal(t, expectedMibEntries, int(mibDb.NumberOfBaselineCommands))

	entry := mibDb.baselineItems[expectedMibEntries-1] // select the last entry, it's the hardcoded packet
	fmt.Println(entry.packet)
	assert.NotNil(t, entry)
	assert.Equal(t, me.ClassID(37), entry.classId)
	assert.Nil(t, entry.entityId)
	assert.Equal(t, 0, len(entry.params))
	assert.NotNil(t, entry.packet)

	// check that we're generating a valid OMCI payload
	packet := gopacket.NewPacket(entry.packet, omci.LayerTypeOMCI, gopacket.Lazy)
	omciLayer := packet.Layer(omci.LayerTypeOMCI)
	assert.NotNil(t, omciLayer)
	omciMsg, ok := omciLayer.(*omci.OMCI)
	assert.True(t, ok)
	assert.Equal(t, omci.MibUploadNextResponseType, omciMsg.MessageType)
	assert.Equal(t, uint16(33066), omciMsg.TransactionID)
}
