/*
 * 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 devices

import (
	"context"
	"testing"
	"time"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/opencord/bbsim/internal/bbsim/responders/dhcp"
	"github.com/opencord/bbsim/internal/common"
	"github.com/opencord/voltha-protos/v5/go/openolt"
	"github.com/stretchr/testify/assert"
)

func getTestOlt(t *testing.T, ctx context.Context, services []common.ServiceYaml) (olt *OltDevice, pon *PonPort, onu *Onu, uni *UniPort, stream *mockStream) {
	common.Services = services

	common.Config = &common.GlobalConfig{
		Olt: common.OltConfig{
			ID:          1,
			NniPorts:    1,
			PonPorts:    1,
			OnusPonPort: 1,
			UniPorts:    1,
		},
	}

	allocIdPerOnu := uint32(common.Config.Olt.UniPorts * uint32(len(common.Services)))
	common.PonsConfig = &common.PonPortsConfig{
		Number: common.Config.Olt.PonPorts,
		Ranges: []common.PonRangeConfig{
			{
				PonRange:     common.IdRange{StartId: 0, EndId: common.Config.Olt.PonPorts - 1},
				Technology:   common.XGSPON.String(),
				OnuRange:     common.IdRange{StartId: 1, EndId: 1 + (common.Config.Olt.OnusPonPort - 1)},
				AllocIdRange: common.IdRange{StartId: 1024, EndId: 1024 + (common.Config.Olt.OnusPonPort * allocIdPerOnu)},
				GemportRange: common.IdRange{StartId: 1024, EndId: 1024 + common.Config.Olt.OnusPonPort*allocIdPerOnu*8},
			},
		},
	}

	olt = CreateOLT(*common.Config, common.Services, true)

	stream = &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	olt.OpenoltStream = stream
	olt.enableContext = ctx

	if len(olt.Pons) <= 0 {
		assert.Fail(t, "No PONs on OLT")
		return
	}
	pon = olt.Pons[0]

	if len(pon.Onus) <= 0 {
		assert.Fail(t, "No ONUs on PON")
		return
	}
	onu = pon.Onus[0]

	if len(onu.UniPorts) <= 0 {
		assert.Fail(t, "No UNIs on ONU")
		return
	}
	uni = onu.UniPorts[0].(*UniPort)

	_, err := olt.ActivateOnu(ctx, &openolt.Onu{
		IntfId:       pon.ID,
		OnuId:        onu.ID,
		SerialNumber: onu.SerialNumber,
	})

	assert.Nil(t, err)

	assert.Equal(t, len(services), len(uni.Services))
	for i, s := range uni.Services {
		service := s.(*Service)
		assert.Equal(t, services[i].Name, service.Name)
		assert.Equal(t, services[i].NeedsDhcp, service.NeedsDhcp)
	}

	err = onu.InternalState.Event(OnuTxInitialize)
	assert.Nil(t, err)

	//A mock ONU won't start processing messages, so we have to call it manually
	go onu.ProcessOnuMessages(ctx, stream, nil)

	err = onu.InternalState.Event(OnuTxDiscover)
	assert.Nil(t, err)
	err = onu.InternalState.Event(OnuTxEnable)
	assert.Nil(t, err)

	err = uni.Enable()
	assert.Nil(t, err)

	return
}

func addTestFlow(t *testing.T, ctx context.Context, olt *OltDevice, onu *Onu, flow openolt.Flow) {
	//Check if the flow is correctly added
	_, err := olt.FlowAdd(ctx, &flow)
	assert.Nil(t, err)
}

func removeTestFlow(t *testing.T, ctx context.Context, olt *OltDevice, onu *Onu, flow openolt.Flow) {
	//Check if the flow is correctly removed
	_, err := olt.FlowRemove(ctx, &flow)
	assert.Nil(t, err)
}

func Test_Flows_FttbTrapRules(t *testing.T) {
	const (
		VID_VENDOR_MGMT      = 6
		VID_NETWORK_DPU_MGMT = 60

		allocId   = int32(1024)
		gemportId = int32(1024)
		uniPortNo = uint32(256)
		nniId     = 0
		nniPortNo = 0x1000000
		pbitNone  = 255

		dhcpServiceName = "dpu_dhcp"
		hsiaServicename = "hsia"
	)

	testServices := []common.ServiceYaml{
		{Name: dhcpServiceName, CTag: 60, CTagAllocation: common.TagAllocationShared.String(), STagAllocation: common.TagAllocationShared.String(), NeedsDhcp: true, TechnologyProfileID: 64},
		{Name: hsiaServicename, UniTagMatch: 4096, CTag: 4096, CTagAllocation: common.TagAllocationShared.String(), STag: 3101, STagAllocation: common.TagAllocationUnique.String(), TechnologyProfileID: 64},
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	olt, pon, onu, uni, stream := getTestOlt(t, ctx, testServices)

	flows := []openolt.Flow{
		{
			AccessIntfId:  int32(pon.ID),
			OnuId:         int32(onu.ID),
			UniId:         int32(uni.ID),
			FlowId:        1,
			FlowType:      flowTypeUpstream,
			AllocId:       allocId,
			NetworkIntfId: nniId,
			GemportId:     gemportId,
			Classifier: &openolt.Classifier{
				OVid:       VID_NETWORK_DPU_MGMT,
				OPbits:     pbitNone,
				EthType:    uint32(layers.EthernetTypeIPv4),
				IpProto:    uint32(layers.IPProtocolUDP),
				SrcPort:    68,
				DstPort:    67,
				PktTagType: flowTagTypeSingle,
			},
			Action: &openolt.Action{
				Cmd: &openolt.ActionCmd{
					TrapToHost: true,
				},
			},
			Priority: 40000,
			PortNo:   uniPortNo,
		},
		{
			AccessIntfId:  -1,
			OnuId:         -1,
			UniId:         -1,
			FlowId:        2,
			FlowType:      flowTypeDownstream,
			AllocId:       -1,
			NetworkIntfId: nniId,
			GemportId:     -1,
			Classifier: &openolt.Classifier{
				OVid:       VID_NETWORK_DPU_MGMT,
				OPbits:     pbitNone,
				EthType:    uint32(layers.EthernetTypeIPv4),
				IpProto:    uint32(layers.IPProtocolUDP),
				SrcPort:    67,
				PktTagType: flowTagTypeDouble,
			},
			Action: &openolt.Action{
				Cmd: &openolt.ActionCmd{
					TrapToHost: true,
				},
			},
			Priority: 40000,
			PortNo:   nniPortNo,
		},
	}

	for _, f := range flows {
		addTestFlow(t, ctx, olt, onu, f)
	}

	//Wait a bit for messages on various channels to be processed
	time.Sleep(time.Second)

	//Check if a DHCP request is sent correctly after trap rules have been added
	assert.True(t, stream.CallCount > 0)
	dhcpCall := stream.Calls[stream.CallCount]

	switch ind := dhcpCall.Data.(type) {
	case *openolt.Indication_PktInd:
		assert.Equal(t, uniPortNo, ind.PktInd.PortNo)
		assert.Equal(t, pon.ID, ind.PktInd.IntfId)
		assert.Equal(t, "pon", ind.PktInd.IntfType)
		assert.Equal(t, uint32(gemportId), ind.PktInd.GemportId)

		packet := gopacket.NewPacket(ind.PktInd.Pkt, layers.LayerTypeEthernet, gopacket.Default)
		_, err := dhcp.GetDhcpLayer(packet)
		assert.Nil(t, err)
	default:
		assert.Fail(t, "Wrong indication type for DHCP request")
	}

	for _, f := range flows {
		removeTestFlow(t, ctx, olt, onu, f)
	}
}
