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

	"github.com/looplab/fsm"
	"github.com/opencord/voltha-protos/v5/go/openolt"
	log "github.com/sirupsen/logrus"
)

var ponLogger = log.WithFields(log.Fields{
	"module": "PON",
})

type AllocIDVal struct {
	OnuSn   *openolt.SerialNumber
	AllocID uint16
}

type AllocIDKey struct {
	PonID    uint32
	OnuID    uint32
	EntityID uint16
}

type PonPort struct {
	// BBSIM Internals
	ID            uint32
	NumOnu        int
	Onus          []*Onu
	Olt           *OltDevice
	PacketCount   uint64
	InternalState *fsm.FSM

	// PON Attributes
	OperState *fsm.FSM
	Type      string

	// Allocated resources
	// Some resources (eg: OnuId, AllocId and GemPorts) have to be unique per PON port
	// we are keeping a list so that we can throw an error in cases we receive duplicates
	AllocatedGemPorts     map[uint16]*openolt.SerialNumber
	allocatedGemPortsLock sync.RWMutex
	AllocatedOnuIds       map[uint32]*openolt.SerialNumber
	allocatedOnuIdsLock   sync.RWMutex
	AllocatedAllocIds     map[AllocIDKey]*AllocIDVal // key is AllocIDKey
	allocatedAllocIdsLock sync.RWMutex
}

// CreatePonPort creates pon port object
func CreatePonPort(olt *OltDevice, id uint32) *PonPort {

	ponPort := PonPort{
		NumOnu:            olt.NumOnuPerPon,
		ID:                id,
		Type:              "pon",
		Olt:               olt,
		Onus:              []*Onu{},
		AllocatedGemPorts: make(map[uint16]*openolt.SerialNumber),
		AllocatedOnuIds:   make(map[uint32]*openolt.SerialNumber),
		AllocatedAllocIds: make(map[AllocIDKey]*AllocIDVal),
	}

	ponPort.InternalState = fsm.NewFSM(
		"created",
		fsm.Events{
			{Name: "enable", Src: []string{"created", "disabled"}, Dst: "enabled"},
			{Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
		},
		fsm.Callbacks{
			"enter_enabled": func(e *fsm.Event) {
				ponLogger.WithFields(log.Fields{
					"ID": ponPort.ID,
				}).Debugf("Changing PON Port InternalState from %s to %s", e.Src, e.Dst)

				if e.Src == "created" {
					if olt.ControlledActivation == Default || olt.ControlledActivation == OnlyPON {
						for _, onu := range ponPort.Onus {
							if err := onu.InternalState.Event(OnuTxInitialize); err != nil {
								ponLogger.Errorf("Error initializing ONU: %v", err)
								continue
							}
							if err := onu.InternalState.Event(OnuTxDiscover); err != nil {
								ponLogger.Errorf("Error discover ONU: %v", err)
							}
						}
					}
				} else if e.Src == "disabled" {
					if ponPort.Olt.ControlledActivation == OnlyONU || ponPort.Olt.ControlledActivation == Both {
						// if ONUs are manually activated then only initialize them
						for _, onu := range ponPort.Onus {
							if err := onu.InternalState.Event(OnuTxInitialize); err != nil {
								ponLogger.WithFields(log.Fields{
									"Err":    err,
									"OnuSn":  onu.Sn(),
									"IntfId": onu.PonPortID,
								}).Error("Error initializing ONU")
								continue
							}
						}
					} else {
						for _, onu := range ponPort.Onus {
							if onu.InternalState.Current() == OnuStatePonDisabled {
								if err := onu.InternalState.Event(OnuTxEnable); err != nil {
									ponLogger.WithFields(log.Fields{
										"Err":    err,
										"OnuSn":  onu.Sn(),
										"IntfId": onu.PonPortID,
									}).Error("Error enabling ONU")
								}
							} else if onu.InternalState.Current() == OnuStateDisabled {
								if err := onu.InternalState.Event(OnuTxInitialize); err != nil {
									ponLogger.WithFields(log.Fields{
										"Err":    err,
										"OnuSn":  onu.Sn(),
										"IntfId": onu.PonPortID,
									}).Error("Error initializing ONU")
									continue
								}
								if err := onu.InternalState.Event(OnuTxDiscover); err != nil {
									ponLogger.WithFields(log.Fields{
										"Err":    err,
										"OnuSn":  onu.Sn(),
										"IntfId": onu.PonPortID,
									}).Error("Error discovering ONU")
								}
							} else if onu.InternalState.Current() == OnuStateInitialized {
								if err := onu.InternalState.Event(OnuTxDiscover); err != nil {
									ponLogger.WithFields(log.Fields{
										"Err":    err,
										"OnuSn":  onu.Sn(),
										"IntfId": onu.PonPortID,
									}).Error("Error discovering ONU")
								}
							} else {
								// this is to loudly report unexpected states in order to address them
								ponLogger.WithFields(log.Fields{
									"OnuSn":         onu.Sn(),
									"IntfId":        onu.PonPortID,
									"InternalState": onu.InternalState.Current(),
								}).Error("Unexpected ONU state in PON enabling")
							}
						}
					}
				}
			},
			"enter_disabled": func(e *fsm.Event) {
				for _, onu := range ponPort.Onus {
					if onu.InternalState.Current() == OnuStateInitialized || onu.InternalState.Current() == OnuStateDisabled {
						continue
					}
					if err := onu.InternalState.Event(OnuTxPonDisable); err != nil {
						ponLogger.Errorf("Failed to move ONU in %s states: %v", OnuStatePonDisabled, err)
					}
				}
			},
		},
	)

	ponPort.OperState = fsm.NewFSM(
		"down",
		fsm.Events{
			{Name: "enable", Src: []string{"down"}, Dst: "up"},
			{Name: "disable", Src: []string{"up"}, Dst: "down"},
		},
		fsm.Callbacks{
			"enter_up": func(e *fsm.Event) {
				ponLogger.WithFields(log.Fields{
					"ID": ponPort.ID,
				}).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
				olt.sendPonIndication(ponPort.ID)
			},
			"enter_down": func(e *fsm.Event) {
				ponLogger.WithFields(log.Fields{
					"ID": ponPort.ID,
				}).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
				olt.sendPonIndication(ponPort.ID)
			},
		},
	)
	return &ponPort
}

func (p *PonPort) GetOnuBySn(sn *openolt.SerialNumber) (*Onu, error) {
	for _, onu := range p.Onus {
		if bytes.Equal(onu.SerialNumber.VendorSpecific, sn.VendorSpecific) {
			return onu, nil
		}
	}
	return nil, fmt.Errorf("Cannot find Onu with serial number %d in PonPort %d", sn, p.ID)
}

func (p *PonPort) GetOnuById(id uint32) (*Onu, error) {
	for _, onu := range p.Onus {
		if onu.ID == id {
			return onu, nil
		}
	}
	return nil, fmt.Errorf("Cannot find Onu with id %d in PonPort %d", id, p.ID)
}

// GetNumOfActiveOnus returns number of active ONUs for PON port
func (p *PonPort) GetNumOfActiveOnus() uint32 {
	var count uint32 = 0
	for _, onu := range p.Onus {
		if onu.InternalState.Current() == OnuStateInitialized || onu.InternalState.Current() == OnuStateCreated || onu.InternalState.Current() == OnuStateDisabled {
			continue
		}
		count++
	}
	return count
}

// storeOnuId adds the Id to the ONU Ids already allocated to this PON port
func (p *PonPort) storeOnuId(onuId uint32, onuSn *openolt.SerialNumber) {
	p.allocatedOnuIdsLock.Lock()
	defer p.allocatedOnuIdsLock.Unlock()
	p.AllocatedOnuIds[onuId] = onuSn
}

// removeOnuId removes the OnuId from the allocated resources
func (p *PonPort) removeOnuId(onuId uint32) {
	p.allocatedOnuIdsLock.Lock()
	defer p.allocatedOnuIdsLock.Unlock()
	delete(p.AllocatedOnuIds, onuId)
}

func (p *PonPort) removeAllOnuIds() {
	p.allocatedOnuIdsLock.Lock()
	defer p.allocatedOnuIdsLock.Unlock()
	p.AllocatedOnuIds = make(map[uint32]*openolt.SerialNumber)
}

// isOnuIdAllocated returns whether this OnuId is already in use on this PON
func (p *PonPort) isOnuIdAllocated(onuId uint32) (bool, *openolt.SerialNumber) {
	p.allocatedOnuIdsLock.RLock()
	defer p.allocatedOnuIdsLock.RUnlock()

	if _, ok := p.AllocatedOnuIds[onuId]; ok {
		return true, p.AllocatedOnuIds[onuId]
	}
	return false, nil
}

// storeGemPort adds the gemPortId to the gemports already allocated to this PON port
func (p *PonPort) storeGemPort(gemPortId uint16, onuSn *openolt.SerialNumber) {
	p.allocatedGemPortsLock.Lock()
	defer p.allocatedGemPortsLock.Unlock()
	p.AllocatedGemPorts[gemPortId] = onuSn
}

// removeGemPort removes the gemPortId from the allocated resources
func (p *PonPort) removeGemPort(gemPortId uint16) {
	p.allocatedGemPortsLock.Lock()
	defer p.allocatedGemPortsLock.Unlock()
	delete(p.AllocatedGemPorts, gemPortId)
}

func (p *PonPort) removeGemPortBySn(onuSn *openolt.SerialNumber) {
	p.allocatedGemPortsLock.Lock()
	defer p.allocatedGemPortsLock.Unlock()
	for gemPort, sn := range p.AllocatedGemPorts {
		if sn == onuSn {
			delete(p.AllocatedGemPorts, gemPort)
		}
	}
}

func (p *PonPort) removeAllGemPorts() {
	p.allocatedGemPortsLock.Lock()
	defer p.allocatedGemPortsLock.Unlock()
	p.AllocatedGemPorts = make(map[uint16]*openolt.SerialNumber)
}

// isGemPortAllocated returns whether this gemPort is already in use on this PON
func (p *PonPort) isGemPortAllocated(gemPortId uint16) (bool, *openolt.SerialNumber) {
	p.allocatedGemPortsLock.RLock()
	defer p.allocatedGemPortsLock.RUnlock()

	if _, ok := p.AllocatedGemPorts[gemPortId]; ok {
		return true, p.AllocatedGemPorts[gemPortId]
	}
	return false, nil
}

// storeAllocId adds the Id to the ONU Ids already allocated to this PON port
func (p *PonPort) storeAllocId(ponID uint32, onuID uint32, entityID uint16, allocId uint16, onuSn *openolt.SerialNumber) {
	p.allocatedAllocIdsLock.Lock()
	defer p.allocatedAllocIdsLock.Unlock()
	p.AllocatedAllocIds[AllocIDKey{ponID, onuID, entityID}] = &AllocIDVal{onuSn, allocId}
}

// removeAllocId removes the AllocId from the allocated resources
func (p *PonPort) removeAllocId(ponID uint32, onuID uint32, entityID uint16) {
	p.allocatedAllocIdsLock.Lock()
	defer p.allocatedAllocIdsLock.Unlock()
	allocKey := AllocIDKey{ponID, onuID, entityID}
	delete(p.AllocatedAllocIds, allocKey)
}

// removeAllocIdsForOnuSn removes the all AllocIds for the given onu serial number
func (p *PonPort) removeAllocIdsForOnuSn(onuSn *openolt.SerialNumber) {
	p.allocatedAllocIdsLock.Lock()
	defer p.allocatedAllocIdsLock.Unlock()
	for id, allocObj := range p.AllocatedAllocIds {
		if onuSn == allocObj.OnuSn {
			delete(p.AllocatedAllocIds, id)
		}
	}
}

func (p *PonPort) removeAllAllocIds() {
	p.allocatedAllocIdsLock.Lock()
	defer p.allocatedAllocIdsLock.Unlock()
	p.AllocatedAllocIds = make(map[AllocIDKey]*AllocIDVal)
}

// isAllocIdAllocated returns whether this AllocId is already in use on this PON
func (p *PonPort) isAllocIdAllocated(ponID uint32, onuID uint32, entityID uint16) (bool, *AllocIDVal) {
	p.allocatedAllocIdsLock.RLock()
	defer p.allocatedAllocIdsLock.RUnlock()
	allocKey := AllocIDKey{ponID, onuID, entityID}
	if _, ok := p.AllocatedAllocIds[allocKey]; ok {
		return true, p.AllocatedAllocIds[allocKey]
	}
	return false, nil
}
