/*
 * 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 (
	"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())
}
