/*
 * Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors

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

	"github.com/google/gopacket/layers"
	"github.com/looplab/fsm"
	"github.com/opencord/bbsim/internal/bbsim/packetHandlers"
	bbsimTypes "github.com/opencord/bbsim/internal/bbsim/types"
	"github.com/opencord/bbsim/internal/common"
	omcilib "github.com/opencord/bbsim/internal/common/omci"
	log "github.com/sirupsen/logrus"
)

var uniLogger = log.WithFields(log.Fields{
	"module": "UNI",
})

const (
	maxUniPorts = 4

	UniStateUp   = "up"
	UniStateDown = "down"

	uniTxEnable  = "enable"
	uniTxDisable = "disable"
)

type UniPortIf interface {
	GetID() uint32
	StorePortNo(portNo uint32)
	UpdateStream(stream bbsimTypes.Stream)
	Enable() error
	Disable() error

	HandlePackets()                  // start listening on the PacketCh
	HandleAuth()                     // Sends the EapoStart packet
	HandleDhcp(pbit uint8, cTag int) // Sends the DHCPDiscover packet
}

type UniPort struct {
	ID        uint32
	MeId      omcilib.EntityID
	PortNo    uint32
	OperState *fsm.FSM
	Onu       *Onu
	Services  []ServiceIf
	logger    *log.Entry
	PacketCh  chan bbsimTypes.OnuPacketMessage // handle packets
}

func NewUniPort(ID uint32, onu *Onu, nextCtag map[string]int, nextStag map[string]int) (*UniPort, error) {

	// IDs starts from 0, thus the maximum UNI supported is maxUniPorts - 1
	if ID > (maxUniPorts - 1) {
		return nil, fmt.Errorf("%d-is-higher-than-the-maximum-supported-unis-%d", ID, maxUniPorts)
	}

	uni := UniPort{
		ID:   ID,
		Onu:  onu,
		MeId: omcilib.GenerateUniPortEntityId(ID + 1),
	}

	uni.logger = uniLogger.WithFields(log.Fields{
		"UniId": uni.ID,
		"OnuSn": onu.Sn(),
	})

	uni.OperState = fsm.NewFSM(
		"down",
		fsm.Events{
			{Name: uniTxEnable, Src: []string{UniStateDown}, Dst: UniStateUp},
			{Name: uniTxDisable, Src: []string{UniStateUp}, Dst: UniStateDown},
		},
		fsm.Callbacks{
			"enter_state": func(e *fsm.Event) {
				uni.logger.Debugf("changing-uni-operstate-from-%s-to-%s", e.Src, e.Dst)
			},
			fmt.Sprintf("enter_%s", UniStateUp): func(e *fsm.Event) {
				msg := bbsimTypes.Message{
					Type: bbsimTypes.UniStatusAlarm,
					Data: bbsimTypes.UniStatusAlarmMessage{
						OnuSN:          uni.Onu.SerialNumber,
						OnuID:          uni.Onu.ID,
						AdminState:     0,
						EntityID:       uni.MeId.ToUint16(),
						RaiseOMCIAlarm: false, // never raise an LOS when enabling a UNI
					},
				}
				uni.Onu.Channel <- msg
				go uni.HandlePackets()
				for _, s := range uni.Services {
					s.Initialize(uni.Onu.PonPort.Olt.OpenoltStream)
				}
			},
			fmt.Sprintf("enter_%s", UniStateDown): func(e *fsm.Event) {
				msg := bbsimTypes.Message{
					Type: bbsimTypes.UniStatusAlarm,
					Data: bbsimTypes.UniStatusAlarmMessage{
						OnuSN:          uni.Onu.SerialNumber,
						OnuID:          uni.Onu.ID,
						AdminState:     1,
						EntityID:       uni.MeId.ToUint16(),
						RaiseOMCIAlarm: true, // raise an LOS when disabling a UNI
					},
				}
				uni.Onu.Channel <- msg
				for _, s := range uni.Services {
					s.Disable()
				}
			},
		},
	)

	for k, s := range common.Services {

		// find the correct cTag for this service
		if _, ok := nextCtag[s.Name]; !ok {
			// it's the first time we iterate over this service,
			// so we start from the config value
			nextCtag[s.Name] = s.CTag
		} else {
			// we have a previous value, so we check it
			// if Allocation is unique, we increment,
			// otherwise (shared) we do nothing
			if s.CTagAllocation == common.TagAllocationUnique.String() {
				nextCtag[s.Name] = nextCtag[s.Name] + 1

				// the max valid value for a tag is 4096
				// check we're not going over
				if nextCtag[s.Name] > 4096 {
					uni.logger.WithFields(log.Fields{
						"cTag":    nextCtag[s.Name],
						"Service": s.Name,
					}).Fatal("c-tag-limit-reached-too-many-subscribers")
				}
			}
		}

		// find the correct sTag for this service
		if _, ok := nextStag[s.Name]; !ok {
			nextStag[s.Name] = s.STag
		} else {
			if s.STagAllocation == common.TagAllocationUnique.String() {
				nextStag[s.Name] = nextStag[s.Name] + 1

				// the max valid value for a tag is 4096
				// check we're not going over
				if nextStag[s.Name] > 4096 {
					uni.logger.WithFields(log.Fields{
						"sTag":    nextStag[s.Name],
						"Service": s.Name,
					}).Fatal("s-tag-limit-reached-too-many-subscribers")
				}
			}
		}

		mac := net.HardwareAddr{0x2e, byte(olt.ID), byte(onu.PonPortID), byte(onu.ID), byte(uni.ID), byte(k)}
		service, err := NewService(uint32(k), s.Name, mac, &uni, nextCtag[s.Name], nextStag[s.Name],
			s.NeedsEapol, s.NeedsDhcp, s.NeedsIgmp, s.NeedsPPPoE, s.TechnologyProfileID, s.UniTagMatch,
			s.ConfigureMacAddress, s.EnableMacLearning, s.UsPonCTagPriority, s.UsPonSTagPriority,
			s.DsPonCTagPriority, s.DsPonSTagPriority)

		if err != nil {
			oltLogger.WithFields(log.Fields{
				"Err": err.Error(),
			}).Fatal("Can't create Service")
		}

		uni.Services = append(uni.Services, service)
	}

	uni.PacketCh = make(chan bbsimTypes.OnuPacketMessage)

	return &uni, nil
}

func (u *UniPort) GetID() uint32 {
	return u.ID
}

func (u *UniPort) StorePortNo(portNo uint32) {
	u.PortNo = portNo
	u.logger.WithFields(log.Fields{
		"PortNo": portNo,
	}).Debug("logical-port-number-added-to-uni")
}

func (u *UniPort) UpdateStream(stream bbsimTypes.Stream) {
	for _, service := range u.Services {
		service.UpdateStream(stream)
	}
}

func (u *UniPort) Enable() error {
	return u.OperState.Event(uniTxEnable)
}

func (u *UniPort) Disable() error {
	if u.OperState.Is(UniStateDown) {
		return nil
	}
	return u.OperState.Event(uniTxDisable)
}

// this method simply forwards the packet to the correct service
func (u *UniPort) HandlePackets() {
	u.logger.Debug("listening-on-uni-packet-channel")

	defer func() {
		u.logger.Debug("done-listening-on-uni-packet-channel")
	}()

	for msg := range u.PacketCh {
		u.logger.WithFields(log.Fields{
			"messageType": msg.Type,
		}).Trace("received-message-on-uni-packet-channel")

		if msg.Type == packetHandlers.EAPOL || msg.Type == packetHandlers.DHCP {
			service, err := u.findServiceByMacAddress(msg.MacAddress)
			if err != nil {
				u.logger.WithFields(log.Fields{"err": err}).Error("cannot-process-uni-pkt")
				continue
			}
			service.PacketCh <- msg
		} else if msg.Type == packetHandlers.IGMP {
			//IGMP packets don't refer to any Mac Address, thus
			//if it's an IGMP packet we assume we have a single IGMP service
			for _, s := range u.Services {
				service := s.(*Service)

				if service.NeedsIgmp {
					service.PacketCh <- msg
				}
			}
		}
	}
}

func (u *UniPort) HandleAuth() {
	for _, s := range u.Services {
		s.HandleAuth()
	}
}

func (u *UniPort) HandleDhcp(oPbit uint8, oVid int) {
	for _, s := range u.Services {
		s.HandleDhcp(oPbit, oVid)
	}
}

func (u *UniPort) addGemPortToService(gemport uint32, ethType uint32, oVlan uint32, iVlan uint32) {
	for _, s := range u.Services {
		if service, ok := s.(*Service); ok {
			// EAPOL is a strange case, as packets are untagged
			// but we assume we will have a single service requiring EAPOL
			if ethType == uint32(layers.EthernetTypeEAPOL) && service.NeedsEapol {
				service.GemPort = gemport
			}

			// For DHCP services we single tag the outgoing packets,
			// thus the flow only contains the CTag and we can use that to match the service
			if ethType == uint32(layers.EthernetTypeIPv4) && service.NeedsDhcp && service.CTag == int(oVlan) {
				service.GemPort = gemport
			}

			// for dataplane services match both C and S tags
			if service.CTag == int(iVlan) && service.STag == int(oVlan) {
				service.GemPort = gemport
			}

			// for loggin purpose only
			if service.GemPort == gemport {
				// TODO move to Trace level
				u.logger.WithFields(log.Fields{
					"OnuId":  service.UniPort.Onu.ID,
					"IntfId": service.UniPort.Onu.PonPortID,
					"OnuSn":  service.UniPort.Onu.Sn(),
					"Name":   service.Name,
					"PortNo": service.UniPort.PortNo,
					"UniId":  service.UniPort.ID,
				}).Debug("gem-port-added-to-service")
			}
		}
	}
}

func (u *UniPort) findServiceByMacAddress(macAddress net.HardwareAddr) (*Service, error) {
	for _, s := range u.Services {
		service := s.(*Service)
		if service.HwAddress.String() == macAddress.String() {
			return service, nil
		}
	}
	return nil, fmt.Errorf("cannot-find-service-with-mac-address-%s", macAddress.String())
}
