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

import (
	"fmt"

	"github.com/opencord/voltha-lib-go/v3/pkg/log"
	"github.com/opencord/voltha-protos/v3/go/openolt"
)

type DtStagKey struct {
	ponIntf, onuID, uniID uint32
}

var currDtStag uint32
var DtStag map[DtStagKey]uint32
var DtCtag map[uint32]uint32
var AttCtag map[uint32]uint32
var TtCtag map[uint32]uint32

func init() {
	_, _ = log.AddPackage(log.JSON, log.DebugLevel, nil)
	AttCtag = make(map[uint32]uint32)
	DtCtag = make(map[uint32]uint32)
	DtStag = make(map[DtStagKey]uint32)
	TtCtag = make(map[uint32]uint32)
}

const (
	vendorName = "ABCD"
	// Number of bits for the physical UNI of the ONUs
	bitsForUniID = 4
	// Number of bits for the ONU ID
	bitsForONUID = 8
	//MaxOnusPerPon is Max number of ONUs on any PON port
	MaxOnusPerPon = 1 << bitsForONUID
)

var vendorSpecificId = 1000

func GenerateNextONUSerialNumber() *openolt.SerialNumber {

	vi := []byte(vendorName)

	vendorSpecificId += 1
	vs := []byte(fmt.Sprint(vendorSpecificId))
	// log.Infow("vendor-id-and-vendor-specific", log.Fields{"vi":vi, "vs":vs})
	sn := &openolt.SerialNumber{VendorId: vi, VendorSpecific: vs}
	// log.Infow("serial-num", log.Fields{"sn":sn})

	return sn
}

//MkUniPortNum returns new UNIportNum based on intfID, inuID and uniID
func MkUniPortNum(intfID, onuID, uniID uint32) uint32 {
	var limit = int(onuID)
	if limit > MaxOnusPerPon {
		log.Warn("Warning: exceeded the MAX ONUS per PON")
	}
	return (intfID << (bitsForUniID + bitsForONUID)) | (onuID << bitsForUniID) | uniID
}

func GetAttCtag(ponIntf uint32) uint32 {
	var currCtag uint32
	var ok bool
	if currCtag, ok = AttCtag[ponIntf]; !ok {
		// Start with ctag 2
		AttCtag[ponIntf] = 2
		return AttCtag[ponIntf]
	}
	AttCtag[ponIntf] = currCtag + 1
	return AttCtag[ponIntf]
}

func GetDtCtag(ponIntf uint32) uint32 {
	var currCtag uint32
	var ok bool
	if currCtag, ok = DtCtag[ponIntf]; !ok {
		// Start with ctag 1
		DtCtag[ponIntf] = 1
		return DtCtag[ponIntf]
	}
	DtCtag[ponIntf] = currCtag + 1
	return DtCtag[ponIntf]
}

func GetTtCtag(ponIntf uint32) uint32 {
	var currCtag uint32
	var ok bool
	if currCtag, ok = TtCtag[ponIntf]; !ok {
		// Start with ctag 1
		TtCtag[ponIntf] = 1
		return TtCtag[ponIntf]
	}
	TtCtag[ponIntf] = currCtag + 1
	return TtCtag[ponIntf]
}

func GetAttStag(ponIntf uint32) uint32 {
	// start with stag 2
	return ponIntf + 2
}

func GetDtStag(ponIntf uint32, onuID uint32, uniID uint32) uint32 {
	// Dt workflow requires unique stag for each subscriber
	key := DtStagKey{ponIntf: ponIntf, onuID: onuID, uniID: uniID}

	if value, ok := DtStag[key]; ok {
		return value
	} else {
		DtStag[key] = currDtStag + 1
		currDtStag = DtStag[key]
	}
	return DtStag[key]
}

func GetTtStag(ponIntf uint32) uint32 {
	// start with stag 2
	return ponIntf + 2
}

// TODO: More workflow support to be added here
func GetCtag(workFlowName string, ponIntf uint32) uint32 {
	switch workFlowName {
	case "ATT":
		return GetAttCtag(ponIntf)
	case "DT":
		return GetDtCtag(ponIntf)
	case "TT":
		return GetTtCtag(ponIntf)
	default:
		log.Errorw("unknown-workflowname", log.Fields{"workflow": workFlowName})
	}
	return 0
}

func GetStag(workFlowName string, ponIntf uint32, onuID uint32, uniID uint32) uint32 {
	switch workFlowName {
	case "ATT":
		return GetAttStag(ponIntf)
	case "DT":
		return GetDtStag(ponIntf, onuID, uniID)
	case "TT":
		return GetTtStag(ponIntf)
	default:
		log.Errorw("unknown-workflowname", log.Fields{"workflow": workFlowName})
	}
	return 0
}
