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

import (
	"reflect"
	"sync"

	"github.com/opencord/voltha-bbsim/common/logger"
	openolt "github.com/opencord/voltha-protos/go/openolt"
	log "github.com/sirupsen/logrus"
)

// Constants for the ONU states
const (
	ONU_INACTIVE DeviceState = iota // TODO: Each stage name should be more accurate
	ONU_ACTIVE
	ONU_OMCIACTIVE
	ONU_AUTHENTICATED
	ONU_LOS_RAISED
	ONU_OMCI_CHANNEL_LOS_RAISED
	ONU_LOS_ON_OLT_PON_LOS // TODO give more suitable and crisp name
	ONU_FREE
)

// ONUState maps int value of device state to string
var ONUState = map[DeviceState]string{
	ONU_INACTIVE:                "ONU_INACTIVE",
	ONU_ACTIVE:                  "ONU_ACTIVE",
	ONU_OMCIACTIVE:              "ONU_OMCIACTIVE",
	ONU_AUTHENTICATED:           "ONU_AUTHENTICATED",
	ONU_LOS_RAISED:              "ONU_LOS_RAISED",
	ONU_OMCI_CHANNEL_LOS_RAISED: "ONU_OMCI_CHANNEL_LOS_RAISED",
	ONU_LOS_ON_OLT_PON_LOS:      "ONU_LOS_ON_OLT_PON_LOS",
	ONU_FREE:                    "ONU_FREE",
}

// Onu structure stores information of ONUs
type Onu struct {
	InternalState DeviceState
	OltID         uint32
	IntfID        uint32
	OperState     string
	SerialNumber  *openolt.SerialNumber
	OnuID         uint32
	GemportID     uint16
	FlowIDs       []uint32
	mu            *sync.Mutex
}

// NewSN constructs and returns serial number based on the OLT ID, intf ID and ONU ID
func NewSN(oltid uint32, intfid uint32, onuid uint32) []byte {
	sn := []byte{0, byte(oltid % 256), byte(intfid), byte(onuid)}
	return sn
}

// NewOnus initializes and returns slice of Onu objects
func NewOnus(oltid uint32, intfid uint32, nonus uint32, nnni uint32) []*Onu {
	onus := []*Onu{}
	for i := 1; i <= int(nonus); i++ {
		onu := Onu{}
		onu.InternalState = ONU_FREE // New Onu Initialised with state ONU_FREE
		onu.mu = &sync.Mutex{}
		onu.IntfID = intfid
		onu.OltID = oltid
		onu.OperState = "down"
		onu.SerialNumber = new(openolt.SerialNumber)
		onu.SerialNumber.VendorId = []byte("BBSM")
		onu.SerialNumber.VendorSpecific = NewSN(oltid, intfid, uint32(i))
		onu.GemportID = 0
		onus = append(onus, &onu)
	}
	return onus
}

// Initialize method initializes ONU state to up and ONU_INACTIVE
func (onu *Onu) Initialize() {
	onu.OperState = "up"
	onu.InternalState = ONU_INACTIVE
}

// ValidateONU method validate ONU based on the serial number in onuMap
func ValidateONU(targetonu openolt.Onu, regonus map[uint32][]*Onu) bool {
	for _, onus := range regonus {
		for _, onu := range onus {
			if ValidateSN(*targetonu.SerialNumber, *onu.SerialNumber) {
				return true
			}
		}
	}
	return false
}

// ValidateSN compares two serial numbers and returns result as true/false
func ValidateSN(sn1 openolt.SerialNumber, sn2 openolt.SerialNumber) bool {
	return reflect.DeepEqual(sn1.VendorId, sn2.VendorId) && reflect.DeepEqual(sn1.VendorSpecific, sn2.VendorSpecific)
}

// UpdateOnusOpStatus method updates ONU oper status
func UpdateOnusOpStatus(ponif uint32, onu *Onu, opstatus string) {
	onu.OperState = opstatus
	logger.WithFields(log.Fields{
		"onu":           onu.SerialNumber,
		"pon_interface": ponif,
	}).Info("ONU OperState Updated")
}

// UpdateIntState method updates ONU internal state
func (onu *Onu) UpdateIntState(intstate DeviceState) {
	onu.mu.Lock()
	defer onu.mu.Unlock()
	onu.InternalState = intstate
}

// GetDevkey returns ONU device key
func (onu *Onu) GetDevkey() Devkey {
	return Devkey{ID: onu.OnuID, Intfid: onu.IntfID}
}

// GetIntState returns ONU internal state
func (onu *Onu) GetIntState() DeviceState {
	onu.mu.Lock()
	defer onu.mu.Unlock()
	return onu.InternalState
}

// DeleteFlowID method search and delete flowID from the onu flowIDs slice
func (onu *Onu) DeleteFlowID(flowID uint32) {
	for pos, id := range onu.FlowIDs {
		if id == flowID {
			// delete the flowID by shifting all flowIDs by one
			onu.FlowIDs = append(onu.FlowIDs[:pos], onu.FlowIDs[pos+1:]...)
			t := make([]uint32, len(onu.FlowIDs))
			copy(t, onu.FlowIDs)
			onu.FlowIDs = t
			break
		}
	}
}
