/*
 * Copyright 2019-2024 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 techprofile

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
	"github.com/opencord/voltha-lib-go/v7/pkg/db"
	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
	"github.com/opencord/voltha-lib-go/v7/pkg/log"
	tp_pb "github.com/opencord/voltha-protos/v5/go/tech_profile"
)

// Interface to pon resource manager APIs
type iPonResourceMgr interface {
	GetResourceID(ctx context.Context, intfID uint32, resourceType string, numIDs uint32) ([]uint32, error)
	FreeResourceID(ctx context.Context, intfID uint32, resourceType string, ReleaseContent []uint32) error
	GetResourceTypeAllocID() string
	GetResourceTypeGemPortID() string
	GetResourceTypeOnuID() string
	GetTechnology() string
}

type SchedulingPolicy int32

const (
	SchedulingPolicy_WRR            SchedulingPolicy = 0
	SchedulingPolicy_StrictPriority SchedulingPolicy = 1
	SchedulingPolicy_Hybrid         SchedulingPolicy = 2
)

type AdditionalBW int32

const (
	AdditionalBW_AdditionalBW_None       AdditionalBW = 0
	AdditionalBW_AdditionalBW_NA         AdditionalBW = 1
	AdditionalBW_AdditionalBW_BestEffort AdditionalBW = 2
	AdditionalBW_AdditionalBW_Auto       AdditionalBW = 3
)

type DiscardPolicy int32

const (
	DiscardPolicy_TailDrop  DiscardPolicy = 0
	DiscardPolicy_WTailDrop DiscardPolicy = 1
	DiscardPolicy_Red       DiscardPolicy = 2
	DiscardPolicy_WRed      DiscardPolicy = 3
)

// Required uniPortName format
var uniPortNameFormatRegexp = regexp.MustCompile(`^olt-{[a-z0-9\-]+}/pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}$`)

// instance control defaults
const (
	defaultOnuInstance    = "multi-instance"
	defaultUniInstance    = "single-instance"
	defaultGemPayloadSize = "auto"
)

// default discard config constants
const (
	defaultMinThreshold   = 0
	defaultMaxThreshold   = 0
	defaultMaxProbability = 0
)

// default scheduler contants
const (
	defaultPriority = 0
	defaultWeight   = 0
)

// default GEM attribute constants
const (
	defaultAESEncryption     = "True"
	defaultPriorityQueue     = 0
	defaultQueueWeight       = 0
	defaultMaxQueueSize      = "auto"
	defaultIsMulticast       = "False"
	defaultAccessControlList = "224.0.0.0-239.255.255.255"
	defaultMcastGemID        = 4069
)

// Default EPON constants
const (
	defaultPakageType = "B"
)
const (
	defaultTrafficType               = "BE"
	defaultUnsolicitedGrantSize      = 0
	defaultNominalInterval           = 0
	defaultToleratedPollJitter       = 0
	defaultRequestTransmissionPolicy = 0
	defaultNumQueueSet               = 2
)
const (
	defaultQThreshold1 = 5500
	defaultQThreshold2 = 0
	defaultQThreshold3 = 0
	defaultQThreshold4 = 0
	defaultQThreshold5 = 0
	defaultQThreshold6 = 0
	defaultQThreshold7 = 0
)

const (
	xgspon = "XGS-PON"
	xgpon  = "XGPON"
	gpon   = "GPON"
	epon   = "EPON"
)

const (
	MaxUniPortPerOnu = 16 // TODO: Adapter uses its own constant for MaxUniPort. How to synchronize this and have a single source of truth?
)

type TechProfileMgr struct {
	config                *TechProfileFlags
	resourceMgr           iPonResourceMgr
	OnuIDMgmtLock         sync.RWMutex
	GemPortIDMgmtLock     sync.RWMutex
	AllocIDMgmtLock       sync.RWMutex
	tpInstanceMap         map[string]*tp_pb.TechProfileInstance // Map of tp path to tp instance
	tpInstanceMapLock     sync.RWMutex
	eponTpInstanceMap     map[string]*tp_pb.EponTechProfileInstance // Map of tp path to epon tp instance
	epontpInstanceMapLock sync.RWMutex
	tpMap                 map[uint32]*tp_pb.TechProfile // Map of tp id to tp
	tpMapLock             sync.RWMutex
	eponTpMap             map[uint32]*tp_pb.EponTechProfile // map of tp id to epon tp
	eponTpMapLock         sync.RWMutex
}

func (t *TechProfileMgr) SetKVClient(ctx context.Context, pathPrefix string) *db.Backend {
	kvClient, err := newKVClient(ctx, t.config.KVStoreType, t.config.KVStoreAddress, t.config.KVStoreTimeout)
	if err != nil {
		logger.Errorw(ctx, "failed-to-create-kv-client",
			log.Fields{
				"type": t.config.KVStoreType, "address": t.config.KVStoreAddress,
				"timeout": t.config.KVStoreTimeout, "prefix": pathPrefix,
				"error": err.Error(),
			})
		return nil
	}
	return &db.Backend{
		Client:     kvClient,
		StoreType:  t.config.KVStoreType,
		Address:    t.config.KVStoreAddress,
		Timeout:    t.config.KVStoreTimeout,
		PathPrefix: pathPrefix}

	/* TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
		  issue between kv store and backend , core is not calling NewBackend directly
	 kv := model.NewBackend(t.config.kvStoreType, t.config.KVStoreHost, t.config.KVStorePort,
								  t.config.KVStoreTimeout,  kvStoreTechProfilePathPrefix)
	*/
}

func (t *TechProfileMgr) CloseKVClient(ctx context.Context) {
	if t.config.KVBackend != nil {
		t.config.KVBackend.Client.Close(ctx)
		t.config.KVBackend = nil
	}
	if t.config.DefaultTpKVBackend != nil {
		t.config.DefaultTpKVBackend.Client.Close(ctx)
		t.config.DefaultTpKVBackend = nil
	}
	if t.config.ResourceInstanceKVBacked != nil {
		t.config.ResourceInstanceKVBacked.Client.Close(ctx)
		t.config.ResourceInstanceKVBacked = nil
	}
}

func NewTechProfile(ctx context.Context, IntfId uint32, deviceId string, resourceMgr iPonResourceMgr, kvStoreType string, kvStoreAddress string, basePathKvStore string) (*TechProfileMgr, error) {
	var techprofileObj TechProfileMgr
	logger.Debug(ctx, "initializing-techprofile-mananger ", log.Fields{"IntId": IntfId, "device-id": deviceId})
	techprofileObj.config = NewTechProfileFlags(kvStoreType, kvStoreAddress, basePathKvStore)
	techprofileObj.config.KVBackend = techprofileObj.SetKVClient(ctx, techprofileObj.config.TPKVPathPrefix)
	techprofileObj.config.DefaultTpKVBackend = techprofileObj.SetKVClient(ctx, techprofileObj.config.defaultTpKvPathPrefix)
	if techprofileObj.config.KVBackend == nil {
		logger.Error(ctx, "failed-to-initialize-backend")
		return nil, errors.New("kv-backend-init-failed")
	}
	techprofileObj.config.ResourceInstanceKVBacked = techprofileObj.SetKVClient(ctx, techprofileObj.config.ResourceInstanceKVPathPrefix)
	if techprofileObj.config.ResourceInstanceKVBacked == nil {
		logger.Error(ctx, "failed-to-initialize-resource-instance-kv-backend")
		return nil, errors.New("resource-instance-kv-backend-init-failed")
	}
	techprofileObj.resourceMgr = resourceMgr
	techprofileObj.tpInstanceMap = make(map[string]*tp_pb.TechProfileInstance)
	techprofileObj.eponTpInstanceMap = make(map[string]*tp_pb.EponTechProfileInstance)
	techprofileObj.tpMap = make(map[uint32]*tp_pb.TechProfile)
	techprofileObj.eponTpMap = make(map[uint32]*tp_pb.EponTechProfile)
	logger.Debug(ctx, "reconcile-tp-instance-cache-start")
	if err := techprofileObj.reconcileTpInstancesToCache(ctx, IntfId, deviceId); err != nil {
		logger.Errorw(ctx, "failed-to-reconcile-tp-instances", log.Fields{"err": err})
		return nil, err
	}
	logger.Debug(ctx, "reconcile-tp-instance-cache-end")
	logger.Debug(ctx, "initializing-tech-profile-manager-object-success")
	return &techprofileObj, nil
}

// GetTechProfileInstanceKey returns the tp instance key that is used to reference TP Instance Map
func (t *TechProfileMgr) GetTechProfileInstanceKey(ctx context.Context, tpID uint32, uniPortName string) string {
	logger.Debugw(ctx, "get-tp-instance-kv-key", log.Fields{
		"uniPortName": uniPortName,
		"tpId":        tpID,
	})
	// Make sure the uniPortName is as per format olt-{[a-z0-9\-]+}/pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}
	if !uniPortNameFormatRegexp.Match([]byte(uniPortName)) {
		logger.Warnw(ctx, "uni-port-name-not-confirming-to-format", log.Fields{"uniPortName": uniPortName})
	}
	// The key path prefix (like service/voltha/technology_profiles or service/voltha_voltha/technology_profiles)
	// is expected to be attached by the components that use this path as part of the KVBackend configuration.
	resourceInstanceKvPathSuffix := "%s/%d/%s" // <technology>/<tpID>/<uni-port-name>
	// <uni-port-name> must be of the format pon-{\d+}/onu-{\d+}/uni-{\d+}
	return fmt.Sprintf(resourceInstanceKvPathSuffix, t.resourceMgr.GetTechnology(), tpID, uniPortName)
}

// GetTPInstance gets TP instance from cache if found
func (t *TechProfileMgr) GetTPInstance(ctx context.Context, path string) (interface{}, error) {
	tech := t.resourceMgr.GetTechnology()
	switch tech {
	case xgspon, xgpon, gpon:
		t.tpInstanceMapLock.RLock()
		defer t.tpInstanceMapLock.RUnlock()
		tpInst, ok := t.tpInstanceMap[path]
		if !ok {
			return nil, fmt.Errorf("tp-instance-not-found-tp-path-%v", path)
		}
		return tpInst, nil
	case epon:
		t.epontpInstanceMapLock.RLock()
		defer t.epontpInstanceMapLock.RUnlock()
		tpInst, ok := t.eponTpInstanceMap[path]
		if !ok {
			return nil, fmt.Errorf("tp-instance-not-found-tp-path-%v", path)
		}
		return tpInst, nil
	default:
		logger.Errorw(ctx, "unknown-tech", log.Fields{"tech": tech})
		return nil, fmt.Errorf("unknown-tech-%s-tp-path-%v", tech, path)
	}
}

// CreateTechProfileInstance creates a new TP instance.
func (t *TechProfileMgr) CreateTechProfileInstance(ctx context.Context, tpID uint32, uniPortName string, intfID uint32) (interface{}, error) {
	var tpInstance *tp_pb.TechProfileInstance
	var eponTpInstance *tp_pb.EponTechProfileInstance

	logger.Infow(ctx, "creating-tp-instance", log.Fields{"tpID": tpID, "uni": uniPortName, "intId": intfID})

	// Make sure the uniPortName is as per format olt-{[a-z0-9\-]+}/pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}
	if !uniPortNameFormatRegexp.Match([]byte(uniPortName)) {
		logger.Errorw(ctx, "uni-port-name-not-confirming-to-format", log.Fields{"uniPortName": uniPortName})
		return nil, fmt.Errorf("uni-port-name-not-confirming-to-format-%s", uniPortName)
	}
	tpInstancePathSuffix := t.GetTechProfileInstanceKey(ctx, tpID, uniPortName)

	if t.resourceMgr.GetTechnology() == epon {
		tp := t.getEponTPFromKVStore(ctx, tpID)
		if tp != nil {
			if err := t.validateInstanceControlAttr(ctx, *tp.InstanceControl); err != nil {
				logger.Error(ctx, "invalid-instance-ctrl-attr-using-default-tp")
				tp = t.getDefaultEponProfile(ctx)
			} else {
				logger.Infow(ctx, "using-specified-tp-from-kv-store", log.Fields{"tpID": tpID})
			}
		} else {
			logger.Info(ctx, "tp-not-found-on-kv--creating-default-tp")
			tp = t.getDefaultEponProfile(ctx)
		}
		// Store TP in cache
		t.eponTpMapLock.Lock()
		t.eponTpMap[tpID] = tp
		t.eponTpMapLock.Unlock()

		if eponTpInstance = t.allocateEponTPInstance(ctx, uniPortName, tp, intfID, tpInstancePathSuffix); eponTpInstance == nil {
			logger.Error(ctx, "tp-instance-allocation-failed")
			return nil, errors.New("tp-instance-allocation-failed")
		}
		t.epontpInstanceMapLock.Lock()
		t.eponTpInstanceMap[tpInstancePathSuffix] = eponTpInstance
		t.epontpInstanceMapLock.Unlock()
		resInst := tp_pb.ResourceInstance{
			TpId:                 tpID,
			ProfileType:          eponTpInstance.ProfileType,
			SubscriberIdentifier: eponTpInstance.SubscriberIdentifier,
			AllocId:              eponTpInstance.AllocId,
		}
		for _, usQAttr := range eponTpInstance.UpstreamQueueAttributeList {
			resInst.GemportIds = append(resInst.GemportIds, usQAttr.GemportId)
		}

		logger.Infow(ctx, "epon-tp-instance-created-successfully",
			log.Fields{"tpID": tpID, "uni": uniPortName, "intfID": intfID})
		if err := t.addResourceInstanceToKVStore(ctx, tpID, uniPortName, resInst); err != nil {
			logger.Errorw(ctx, "failed-to-update-resource-instance-to-kv-store--freeing-up-resources", log.Fields{"err": err, "tpID": tpID, "uniPortName": uniPortName})
			allocIDs := make([]uint32, 0)
			allocIDs = append(allocIDs, resInst.AllocId)
			errList := make([]error, 0)
			errList = append(errList, t.FreeResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeAllocID(), allocIDs))
			errList = append(errList, t.FreeResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeGemPortID(), resInst.GemportIds))
			if len(errList) > 0 {
				logger.Errorw(ctx, "failed-to-free-up-resources-on-kv-store--system-behavior-has-become-erratic", log.Fields{"tpID": tpID, "uniPortName": uniPortName, "errList": errList})
			}
			return nil, err
		}
		return eponTpInstance, nil
	} else {
		tp := t.getTPFromKVStore(ctx, tpID)
		if tp != nil {
			if err := t.validateInstanceControlAttr(ctx, *tp.InstanceControl); err != nil {
				logger.Error(ctx, "invalid-instance-ctrl-attr--using-default-tp")
				tp = t.getDefaultTechProfile(ctx)
			} else {
				logger.Infow(ctx, "using-specified-tp-from-kv-store", log.Fields{"tpID": tpID})
			}
		} else {
			logger.Info(ctx, "tp-not-found-on-kv--creating-default-tp")
			tp = t.getDefaultTechProfile(ctx)
		}
		// Store TP in cache
		t.tpMapLock.Lock()
		t.tpMap[tpID] = tp
		t.tpMapLock.Unlock()

		if tpInstance = t.allocateTPInstance(ctx, uniPortName, tp, intfID, tpInstancePathSuffix); tpInstance == nil {
			logger.Error(ctx, "tp-instance-allocation-failed")
			return nil, errors.New("tp-instance-allocation-failed")
		}
		t.tpInstanceMapLock.Lock()
		t.tpInstanceMap[tpInstancePathSuffix] = tpInstance
		t.tpInstanceMapLock.Unlock()

		resInst := tp_pb.ResourceInstance{
			TpId:                 tpID,
			ProfileType:          tpInstance.ProfileType,
			SubscriberIdentifier: tpInstance.SubscriberIdentifier,
			AllocId:              tpInstance.UsScheduler.AllocId,
		}
		for _, usQAttr := range tpInstance.UpstreamGemPortAttributeList {
			resInst.GemportIds = append(resInst.GemportIds, usQAttr.GemportId)
		}

		logger.Infow(ctx, "tp-instance-created-successfully",
			log.Fields{"tpID": tpID, "uni": uniPortName, "intfID": intfID})
		if err := t.addResourceInstanceToKVStore(ctx, tpID, uniPortName, resInst); err != nil {
			logger.Errorw(ctx, "failed-to-update-resource-instance-to-kv-store--freeing-up-resources", log.Fields{"err": err, "tpID": tpID, "uniPortName": uniPortName})
			allocIDs := make([]uint32, 0)
			allocIDs = append(allocIDs, resInst.AllocId)
			errList := make([]error, 0)
			errList = append(errList, t.FreeResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeAllocID(), allocIDs))
			errList = append(errList, t.FreeResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeGemPortID(), resInst.GemportIds))
			if len(errList) > 0 {
				logger.Fatalw(ctx, "failed-to-free-up-resources-on-kv-store--system-behavior-has-become-erratic", log.Fields{"err": err, "tpID": tpID, "uniPortName": uniPortName})
			}
			return nil, err
		}

		logger.Infow(ctx, "resource-instance-added-to-kv-store-successfully",
			log.Fields{"tpID": tpID, "uni": uniPortName, "intfID": intfID})
		return tpInstance, nil
	}
}

// DeleteTechProfileInstance deletes the TP instance from the local cache as well as deletes the corresponding
// resource instance from the KV store.
func (t *TechProfileMgr) DeleteTechProfileInstance(ctx context.Context, tpID uint32, uniPortName string) error {
	// Make sure the uniPortName is as per format olt-{[a-z0-9\-]+}/pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}
	if !uniPortNameFormatRegexp.Match([]byte(uniPortName)) {
		logger.Errorw(ctx, "uni-port-name-not-confirming-to-format", log.Fields{"uniPortName": uniPortName})
		return fmt.Errorf("uni-port-name-not-confirming-to-format--%s", uniPortName)
	}
	path := t.GetTechProfileInstanceKey(ctx, tpID, uniPortName)
	logger.Infow(ctx, "delete-tp-instance-from-cache", log.Fields{"key": path})
	t.tpInstanceMapLock.Lock()
	delete(t.tpInstanceMap, path)
	t.tpInstanceMapLock.Unlock()
	if err := t.removeResourceInstanceFromKVStore(ctx, tpID, uniPortName); err != nil {
		return err
	}
	return nil
}

func (t *TechProfileMgr) GetMulticastTrafficQueues(ctx context.Context, tp *tp_pb.TechProfileInstance) []*tp_pb.TrafficQueue {
	var encryp bool
	NumGemPorts := len(tp.DownstreamGemPortAttributeList)
	mcastTrafficQueues := make([]*tp_pb.TrafficQueue, 0)
	for Count := 0; Count < NumGemPorts; Count++ {
		if !isMulticastGem(tp.DownstreamGemPortAttributeList[Count].IsMulticast) {
			continue
		}
		if tp.DownstreamGemPortAttributeList[Count].AesEncryption == "True" {
			encryp = true
		} else {
			encryp = false
		}
		mcastTrafficQueues = append(mcastTrafficQueues, &tp_pb.TrafficQueue{
			Direction:     tp_pb.Direction_DOWNSTREAM,
			GemportId:     tp.DownstreamGemPortAttributeList[Count].MulticastGemId,
			PbitMap:       tp.DownstreamGemPortAttributeList[Count].PbitMap,
			AesEncryption: encryp,
			SchedPolicy:   tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy,
			Priority:      tp.DownstreamGemPortAttributeList[Count].PriorityQ,
			Weight:        tp.DownstreamGemPortAttributeList[Count].Weight,
			DiscardPolicy: tp.DownstreamGemPortAttributeList[Count].DiscardPolicy,
		})
	}
	logger.Debugw(ctx, "Downstream Multicast Traffic queue list ", log.Fields{"queuelist": mcastTrafficQueues})
	return mcastTrafficQueues
}

func (t *TechProfileMgr) GetGemportForPbit(ctx context.Context, tp interface{}, dir tp_pb.Direction, pbit uint32) interface{} {
	/*
	  Function to get the Gemport mapped to a pbit.
	*/
	switch tp := tp.(type) {
	case *tp_pb.TechProfileInstance:
		if dir == tp_pb.Direction_UPSTREAM {
			// upstream GEM ports
			numGemPorts := len(tp.UpstreamGemPortAttributeList)
			for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
				lenOfPbitMap := len(tp.UpstreamGemPortAttributeList[gemCnt].PbitMap)
				for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
					// Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
					// "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
					if p, err := strconv.Atoi(string(tp.UpstreamGemPortAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
						if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
							logger.Debugw(ctx, "Found-US-GEMport-for-Pcp", log.Fields{"pbit": pbit, "GEMport": tp.UpstreamGemPortAttributeList[gemCnt].GemportId})
							return tp.UpstreamGemPortAttributeList[gemCnt]
						}
					}
				}
			}
		} else if dir == tp_pb.Direction_DOWNSTREAM {
			//downstream GEM ports
			numGemPorts := len(tp.DownstreamGemPortAttributeList)
			for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
				lenOfPbitMap := len(tp.DownstreamGemPortAttributeList[gemCnt].PbitMap)
				for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
					// Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
					// "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
					if p, err := strconv.Atoi(string(tp.DownstreamGemPortAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
						if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
							logger.Debugw(ctx, "Found-DS-GEMport-for-Pcp", log.Fields{"pbit": pbit, "GEMport": tp.DownstreamGemPortAttributeList[gemCnt].GemportId})
							return tp.DownstreamGemPortAttributeList[gemCnt]
						}
					}
				}
			}
		}
		logger.Errorw(ctx, "No-GemportId-Found-For-Pcp", log.Fields{"pcpVlan": pbit})
	case *tp_pb.EponTechProfileInstance:
		if dir == tp_pb.Direction_UPSTREAM {
			// upstream GEM ports
			numGemPorts := len(tp.UpstreamQueueAttributeList)
			for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
				lenOfPbitMap := len(tp.UpstreamQueueAttributeList[gemCnt].PbitMap)
				for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
					// Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
					// "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
					if p, err := strconv.Atoi(string(tp.UpstreamQueueAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
						if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
							logger.Debugw(ctx, "Found-US-Queue-for-Pcp", log.Fields{"pbit": pbit, "Queue": tp.UpstreamQueueAttributeList[gemCnt].GemportId})
							return tp.UpstreamQueueAttributeList[gemCnt]
						}
					}
				}
			}
		} else if dir == tp_pb.Direction_DOWNSTREAM {
			//downstream GEM ports
			numGemPorts := len(tp.DownstreamQueueAttributeList)
			for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
				lenOfPbitMap := len(tp.DownstreamQueueAttributeList[gemCnt].PbitMap)
				for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
					// Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
					// "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
					if p, err := strconv.Atoi(string(tp.DownstreamQueueAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
						if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
							logger.Debugw(ctx, "Found-DS-Queue-for-Pcp", log.Fields{"pbit": pbit, "Queue": tp.DownstreamQueueAttributeList[gemCnt].GemportId})
							return tp.DownstreamQueueAttributeList[gemCnt]
						}
					}
				}
			}
		}
		logger.Errorw(ctx, "No-QueueId-Found-For-Pcp", log.Fields{"pcpVlan": pbit})
	default:
		logger.Errorw(ctx, "unknown-tech", log.Fields{"tp": tp})
	}
	return nil
}

// FindAllTpInstances returns all TechProfile instances for a given TechProfile table-id, pon interface ID and onu ID.
func (t *TechProfileMgr) FindAllTpInstances(ctx context.Context, oltDeviceID string, tpID uint32, intfID uint32, onuID uint32) interface{} {
	onuTpInstancePathSuffix := fmt.Sprintf("%s/%d/olt-{%s}/pon-{%d}/onu-{%d}", t.resourceMgr.GetTechnology(), tpID, oltDeviceID, intfID, onuID)
	tech := t.resourceMgr.GetTechnology()
	if tech == xgspon || tech == xgpon || tech == gpon {
		t.tpInstanceMapLock.RLock()
		defer t.tpInstanceMapLock.RUnlock()
		tpInstancesTech := make([]tp_pb.TechProfileInstance, 0)
		for i := 0; i < MaxUniPortPerOnu; i++ {
			key := onuTpInstancePathSuffix + fmt.Sprintf("/uni-{%d}", i)
			if tpInst, ok := t.tpInstanceMap[key]; ok {
				tpInstancesTech = append(tpInstancesTech, *tpInst)
			}
		}
		return tpInstancesTech
	} else if tech == epon {
		t.epontpInstanceMapLock.RLock()
		defer t.epontpInstanceMapLock.RUnlock()
		tpInstancesTech := make([]tp_pb.EponTechProfileInstance, 0)
		for i := 0; i < MaxUniPortPerOnu; i++ {
			key := onuTpInstancePathSuffix + fmt.Sprintf("/uni-{%d}", i)
			if tpInst, ok := t.eponTpInstanceMap[key]; ok {
				tpInstancesTech = append(tpInstancesTech, *tpInst)
			}
		}
		return tpInstancesTech
	} else {
		logger.Errorw(ctx, "unknown-tech", log.Fields{"tech": tech, "tpID": tpID, "onuID": onuID, "intfID": intfID})
	}
	return nil
}

func (t *TechProfileMgr) GetResourceID(ctx context.Context, intfID uint32, resourceType string, numIDs uint32) ([]uint32, error) {
	logger.Debugw(ctx, "getting-resource-id", log.Fields{
		"intf-id":       intfID,
		"resource-type": resourceType,
		"num":           numIDs,
	})
	var err error
	var ids []uint32
	switch resourceType {
	case t.resourceMgr.GetResourceTypeAllocID():
		t.AllocIDMgmtLock.Lock()
		ids, err = t.resourceMgr.GetResourceID(ctx, intfID, resourceType, numIDs)
		t.AllocIDMgmtLock.Unlock()
	case t.resourceMgr.GetResourceTypeGemPortID():
		t.GemPortIDMgmtLock.Lock()
		ids, err = t.resourceMgr.GetResourceID(ctx, intfID, resourceType, numIDs)
		t.GemPortIDMgmtLock.Unlock()
	case t.resourceMgr.GetResourceTypeOnuID():
		t.OnuIDMgmtLock.Lock()
		ids, err = t.resourceMgr.GetResourceID(ctx, intfID, resourceType, numIDs)
		t.OnuIDMgmtLock.Unlock()
	default:
		return nil, fmt.Errorf("resourceType %s not supported", resourceType)
	}
	if err != nil {
		return nil, err
	}
	return ids, nil
}

func (t *TechProfileMgr) FreeResourceID(ctx context.Context, intfID uint32, resourceType string, ReleaseContent []uint32) error {
	logger.Debugw(ctx, "freeing-resource-id", log.Fields{
		"intf-id":         intfID,
		"resource-type":   resourceType,
		"release-content": ReleaseContent,
	})
	var err error
	switch resourceType {
	case t.resourceMgr.GetResourceTypeAllocID():
		t.AllocIDMgmtLock.Lock()
		err = t.resourceMgr.FreeResourceID(ctx, intfID, resourceType, ReleaseContent)
		t.AllocIDMgmtLock.Unlock()
	case t.resourceMgr.GetResourceTypeGemPortID():
		t.GemPortIDMgmtLock.Lock()
		err = t.resourceMgr.FreeResourceID(ctx, intfID, resourceType, ReleaseContent)
		t.GemPortIDMgmtLock.Unlock()
	case t.resourceMgr.GetResourceTypeOnuID():
		t.OnuIDMgmtLock.Lock()
		err = t.resourceMgr.FreeResourceID(ctx, intfID, resourceType, ReleaseContent)
		t.OnuIDMgmtLock.Unlock()
	default:
		return fmt.Errorf("resourceType %s not supported", resourceType)
	}
	if err != nil {
		return err
	}
	return nil
}

func (t *TechProfileMgr) GetUsScheduler(tpInstance *tp_pb.TechProfileInstance) *tp_pb.SchedulerConfig {
	return &tp_pb.SchedulerConfig{
		Direction:    tpInstance.UsScheduler.Direction,
		AdditionalBw: tpInstance.UsScheduler.AdditionalBw,
		Priority:     tpInstance.UsScheduler.Priority,
		Weight:       tpInstance.UsScheduler.Weight,
		SchedPolicy:  tpInstance.UsScheduler.QSchedPolicy}
}

func (t *TechProfileMgr) GetDsScheduler(tpInstance *tp_pb.TechProfileInstance) *tp_pb.SchedulerConfig {
	return &tp_pb.SchedulerConfig{
		Direction:    tpInstance.DsScheduler.Direction,
		AdditionalBw: tpInstance.DsScheduler.AdditionalBw,
		Priority:     tpInstance.DsScheduler.Priority,
		Weight:       tpInstance.DsScheduler.Weight,
		SchedPolicy:  tpInstance.DsScheduler.QSchedPolicy}
}

func (t *TechProfileMgr) GetTrafficScheduler(tpInstance *tp_pb.TechProfileInstance, SchedCfg *tp_pb.SchedulerConfig,
	ShapingCfg *tp_pb.TrafficShapingInfo) *tp_pb.TrafficScheduler {

	tSched := &tp_pb.TrafficScheduler{
		Direction:          SchedCfg.Direction,
		AllocId:            tpInstance.UsScheduler.AllocId,
		TrafficShapingInfo: ShapingCfg,
		Scheduler:          SchedCfg}

	return tSched
}

func (t *TechProfileMgr) GetTrafficQueues(ctx context.Context, tp *tp_pb.TechProfileInstance, direction tp_pb.Direction) ([]*tp_pb.TrafficQueue, error) {

	var encryp bool
	if direction == tp_pb.Direction_UPSTREAM {
		// upstream GEM ports
		NumGemPorts := len(tp.UpstreamGemPortAttributeList)
		GemPorts := make([]*tp_pb.TrafficQueue, 0)
		for Count := 0; Count < NumGemPorts; Count++ {
			if tp.UpstreamGemPortAttributeList[Count].AesEncryption == "True" {
				encryp = true
			} else {
				encryp = false
			}

			GemPorts = append(GemPorts, &tp_pb.TrafficQueue{
				Direction:     direction,
				GemportId:     tp.UpstreamGemPortAttributeList[Count].GemportId,
				PbitMap:       tp.UpstreamGemPortAttributeList[Count].PbitMap,
				AesEncryption: encryp,
				SchedPolicy:   tp.UpstreamGemPortAttributeList[Count].SchedulingPolicy,
				Priority:      tp.UpstreamGemPortAttributeList[Count].PriorityQ,
				Weight:        tp.UpstreamGemPortAttributeList[Count].Weight,
				DiscardPolicy: tp.UpstreamGemPortAttributeList[Count].DiscardPolicy,
			})
		}
		logger.Debugw(ctx, "Upstream Traffic queue list ", log.Fields{"queuelist": GemPorts})
		return GemPorts, nil
	} else if direction == tp_pb.Direction_DOWNSTREAM {
		//downstream GEM ports
		NumGemPorts := len(tp.DownstreamGemPortAttributeList)
		GemPorts := make([]*tp_pb.TrafficQueue, 0)
		for Count := 0; Count < NumGemPorts; Count++ {
			if isMulticastGem(tp.DownstreamGemPortAttributeList[Count].IsMulticast) {
				//do not take multicast GEM ports. They are handled separately.
				continue
			}
			if tp.DownstreamGemPortAttributeList[Count].AesEncryption == "True" {
				encryp = true
			} else {
				encryp = false
			}

			GemPorts = append(GemPorts, &tp_pb.TrafficQueue{
				Direction:     direction,
				GemportId:     tp.DownstreamGemPortAttributeList[Count].GemportId,
				PbitMap:       tp.DownstreamGemPortAttributeList[Count].PbitMap,
				AesEncryption: encryp,
				SchedPolicy:   tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy,
				Priority:      tp.DownstreamGemPortAttributeList[Count].PriorityQ,
				Weight:        tp.DownstreamGemPortAttributeList[Count].Weight,
				DiscardPolicy: tp.DownstreamGemPortAttributeList[Count].DiscardPolicy,
			})
		}
		logger.Debugw(ctx, "Downstream Traffic queue list ", log.Fields{"queuelist": GemPorts})
		return GemPorts, nil
	}

	logger.Errorf(ctx, "Unsupported direction %s used for generating Traffic Queue list", direction)
	return nil, fmt.Errorf("downstream gem port traffic queue creation failed due to unsupported direction %s", direction)
}

func (t *TechProfileMgr) validateInstanceControlAttr(ctx context.Context, instCtl tp_pb.InstanceControl) error {
	if instCtl.Onu != "single-instance" && instCtl.Onu != "multi-instance" {
		logger.Errorw(ctx, "invalid-onu-instance-control-attribute", log.Fields{"onu-inst": instCtl.Onu})
		return errors.New("invalid-onu-instance-ctl-attr")
	}

	if instCtl.Uni != "single-instance" && instCtl.Uni != "multi-instance" {
		logger.Errorw(ctx, "invalid-uni-instance-control-attribute", log.Fields{"uni-inst": instCtl.Uni})
		return errors.New("invalid-uni-instance-ctl-attr")
	}

	if instCtl.Uni == "multi-instance" {
		logger.Error(ctx, "uni-multi-instance-tp-not-supported")
		return errors.New("uni-multi-instance-tp-not-supported")
	}

	return nil
}

// allocateTPInstance for GPON, XGPON and XGS-PON technology
func (t *TechProfileMgr) allocateTPInstance(ctx context.Context, uniPortName string, tp *tp_pb.TechProfile, intfID uint32, tpInstPathSuffix string) *tp_pb.TechProfileInstance {

	var usGemPortAttributeList []*tp_pb.GemPortAttributes
	var dsGemPortAttributeList []*tp_pb.GemPortAttributes
	var dsMulticastGemAttributeList []*tp_pb.GemPortAttributes
	var dsUnicastGemAttributeList []*tp_pb.GemPortAttributes
	var tcontIDs []uint32
	var gemPorts []uint32
	var err error

	logger.Infow(ctx, "Allocating TechProfileMgr instance from techprofile template", log.Fields{"uniPortName": uniPortName, "intfID": intfID, "numGem": tp.NumGemPorts})

	if tp.InstanceControl.Onu == "multi-instance" {
		tcontIDs, err = t.GetResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeAllocID(), 1)
		if err != nil {
			logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"err": err, "intfID": intfID})
			return nil
		}
	} else { // "single-instance"
		if tpInst := t.getSingleInstanceTp(ctx, tpInstPathSuffix); tpInst == nil {
			// No "single-instance" tp found on one any uni port for the given TP ID
			// Allocate a new TcontID or AllocID
			tcontIDs, err = t.GetResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeAllocID(), 1)
			if err != nil {
				logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"err": err, "intfID": intfID})
				return nil
			}
		} else {
			// Use the alloc-id from the existing TpInstance
			tcontIDs = append(tcontIDs, tpInst.UsScheduler.AllocId)
		}
	}
	logger.Debugw(ctx, "Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
	gemPorts, err = t.GetResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts)
	if err != nil {
		logger.Errorw(ctx, "Error getting gemport ids from rsrcrMgr", log.Fields{"err": err, "intfID": intfID, "numGemports": tp.NumGemPorts})
		return nil
	}
	logger.Infow(ctx, "Allocated tconts and GEM ports successfully", log.Fields{"tconts": tcontIDs, "gemports": gemPorts})
	for index := 0; index < int(tp.NumGemPorts); index++ {
		usGemPortAttributeList = append(usGemPortAttributeList,
			&tp_pb.GemPortAttributes{GemportId: gemPorts[index],
				MaxQSize:         tp.UpstreamGemPortAttributeList[index].MaxQSize,
				PbitMap:          tp.UpstreamGemPortAttributeList[index].PbitMap,
				AesEncryption:    tp.UpstreamGemPortAttributeList[index].AesEncryption,
				SchedulingPolicy: tp.UpstreamGemPortAttributeList[index].SchedulingPolicy,
				PriorityQ:        tp.UpstreamGemPortAttributeList[index].PriorityQ,
				Weight:           tp.UpstreamGemPortAttributeList[index].Weight,
				DiscardPolicy:    tp.UpstreamGemPortAttributeList[index].DiscardPolicy,
				DiscardConfig:    tp.UpstreamGemPortAttributeList[index].DiscardConfig})
	}

	logger.Info(ctx, "length of DownstreamGemPortAttributeList", len(tp.DownstreamGemPortAttributeList))
	//put multicast and unicast downstream GEM port attributes in different lists first
	for index := 0; index < len(tp.DownstreamGemPortAttributeList); index++ {
		if isMulticastGem(tp.DownstreamGemPortAttributeList[index].IsMulticast) {
			dsMulticastGemAttributeList = append(dsMulticastGemAttributeList,
				&tp_pb.GemPortAttributes{
					MulticastGemId:           tp.DownstreamGemPortAttributeList[index].MulticastGemId,
					MaxQSize:                 tp.DownstreamGemPortAttributeList[index].MaxQSize,
					PbitMap:                  tp.DownstreamGemPortAttributeList[index].PbitMap,
					AesEncryption:            tp.DownstreamGemPortAttributeList[index].AesEncryption,
					SchedulingPolicy:         tp.DownstreamGemPortAttributeList[index].SchedulingPolicy,
					PriorityQ:                tp.DownstreamGemPortAttributeList[index].PriorityQ,
					Weight:                   tp.DownstreamGemPortAttributeList[index].Weight,
					DiscardPolicy:            tp.DownstreamGemPortAttributeList[index].DiscardPolicy,
					DiscardConfig:            tp.DownstreamGemPortAttributeList[index].DiscardConfig,
					IsMulticast:              tp.DownstreamGemPortAttributeList[index].IsMulticast,
					DynamicAccessControlList: tp.DownstreamGemPortAttributeList[index].DynamicAccessControlList,
					StaticAccessControlList:  tp.DownstreamGemPortAttributeList[index].StaticAccessControlList})
		} else {
			dsUnicastGemAttributeList = append(dsUnicastGemAttributeList,
				&tp_pb.GemPortAttributes{
					MaxQSize:         tp.DownstreamGemPortAttributeList[index].MaxQSize,
					PbitMap:          tp.DownstreamGemPortAttributeList[index].PbitMap,
					AesEncryption:    tp.DownstreamGemPortAttributeList[index].AesEncryption,
					SchedulingPolicy: tp.DownstreamGemPortAttributeList[index].SchedulingPolicy,
					PriorityQ:        tp.DownstreamGemPortAttributeList[index].PriorityQ,
					Weight:           tp.DownstreamGemPortAttributeList[index].Weight,
					DiscardPolicy:    tp.DownstreamGemPortAttributeList[index].DiscardPolicy,
					DiscardConfig:    tp.DownstreamGemPortAttributeList[index].DiscardConfig})
		}
	}
	//add unicast downstream GEM ports to dsGemPortAttributeList
	if dsUnicastGemAttributeList != nil {
		for index := 0; index < int(tp.NumGemPorts); index++ {
			dsGemPortAttributeList = append(dsGemPortAttributeList,
				&tp_pb.GemPortAttributes{GemportId: gemPorts[index],
					MaxQSize:         dsUnicastGemAttributeList[index].MaxQSize,
					PbitMap:          dsUnicastGemAttributeList[index].PbitMap,
					AesEncryption:    dsUnicastGemAttributeList[index].AesEncryption,
					SchedulingPolicy: dsUnicastGemAttributeList[index].SchedulingPolicy,
					PriorityQ:        dsUnicastGemAttributeList[index].PriorityQ,
					Weight:           dsUnicastGemAttributeList[index].Weight,
					DiscardPolicy:    dsUnicastGemAttributeList[index].DiscardPolicy,
					DiscardConfig:    dsUnicastGemAttributeList[index].DiscardConfig})
		}
	}
	//add multicast GEM ports to dsGemPortAttributeList afterwards
	for k := range dsMulticastGemAttributeList {
		dsGemPortAttributeList = append(dsGemPortAttributeList, dsMulticastGemAttributeList[k])
	}

	return &tp_pb.TechProfileInstance{
		SubscriberIdentifier: uniPortName,
		Name:                 tp.Name,
		ProfileType:          tp.ProfileType,
		Version:              tp.Version,
		NumGemPorts:          tp.NumGemPorts,
		InstanceControl:      tp.InstanceControl,
		UsScheduler: &tp_pb.SchedulerAttributes{
			AllocId:      tcontIDs[0],
			Direction:    tp.UsScheduler.Direction,
			AdditionalBw: tp.UsScheduler.AdditionalBw,
			Priority:     tp.UsScheduler.Priority,
			Weight:       tp.UsScheduler.Weight,
			QSchedPolicy: tp.UsScheduler.QSchedPolicy},
		DsScheduler: &tp_pb.SchedulerAttributes{
			AllocId:      tcontIDs[0],
			Direction:    tp.DsScheduler.Direction,
			AdditionalBw: tp.DsScheduler.AdditionalBw,
			Priority:     tp.DsScheduler.Priority,
			Weight:       tp.DsScheduler.Weight,
			QSchedPolicy: tp.DsScheduler.QSchedPolicy},
		UpstreamGemPortAttributeList:   usGemPortAttributeList,
		DownstreamGemPortAttributeList: dsGemPortAttributeList}
}

// allocateTPInstance function for EPON
func (t *TechProfileMgr) allocateEponTPInstance(ctx context.Context, uniPortName string, tp *tp_pb.EponTechProfile, intfID uint32, tpInstPath string) *tp_pb.EponTechProfileInstance {

	var usQueueAttributeList []*tp_pb.EPONQueueAttributes
	var dsQueueAttributeList []*tp_pb.EPONQueueAttributes
	var tcontIDs []uint32
	var gemPorts []uint32
	var err error

	logger.Infow(ctx, "allocating-tp-instance-from-tp-template", log.Fields{"uniPortName": uniPortName, "intfID": intfID, "numGem": tp.NumGemPorts})

	if tp.InstanceControl.Onu == "multi-instance" {
		if tcontIDs, err = t.GetResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
			logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"err": err, "intfID": intfID})
			return nil
		}
	} else { // "single-instance"
		if tpInst := t.getSingleInstanceEponTp(ctx, tpInstPath); tpInst == nil {
			// No "single-instance" tp found on one any uni port for the given TP ID
			// Allocate a new TcontID or AllocID
			if tcontIDs, err = t.GetResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
				logger.Errorw(ctx, "error-getting-alloc-id-from-resource-mgr", log.Fields{"err": err, "intfID": intfID})
				return nil
			}
		} else {
			// Use the alloc-id from the existing TpInstance
			tcontIDs = append(tcontIDs, tpInst.AllocId)
		}
	}
	logger.Debugw(ctx, "Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
	if gemPorts, err = t.GetResourceID(ctx, intfID, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts); err != nil {
		logger.Errorw(ctx, "error-getting-gemport-id-from-resource-mgr", log.Fields{"err": err, "intfID": intfID, "numGemports": tp.NumGemPorts})
		return nil
	}
	logger.Infow(ctx, "allocated-alloc-id-and-gemport-successfully", log.Fields{"tconts": tcontIDs, "gemports": gemPorts})
	for index := 0; index < int(tp.NumGemPorts); index++ {
		usQueueAttributeList = append(usQueueAttributeList,
			&tp_pb.EPONQueueAttributes{GemportId: gemPorts[index],
				MaxQSize:                  tp.UpstreamQueueAttributeList[index].MaxQSize,
				PbitMap:                   tp.UpstreamQueueAttributeList[index].PbitMap,
				AesEncryption:             tp.UpstreamQueueAttributeList[index].AesEncryption,
				TrafficType:               tp.UpstreamQueueAttributeList[index].TrafficType,
				UnsolicitedGrantSize:      tp.UpstreamQueueAttributeList[index].UnsolicitedGrantSize,
				NominalInterval:           tp.UpstreamQueueAttributeList[index].NominalInterval,
				ToleratedPollJitter:       tp.UpstreamQueueAttributeList[index].ToleratedPollJitter,
				RequestTransmissionPolicy: tp.UpstreamQueueAttributeList[index].RequestTransmissionPolicy,
				NumQSets:                  tp.UpstreamQueueAttributeList[index].NumQSets,
				QThresholds:               tp.UpstreamQueueAttributeList[index].QThresholds,
				SchedulingPolicy:          tp.UpstreamQueueAttributeList[index].SchedulingPolicy,
				PriorityQ:                 tp.UpstreamQueueAttributeList[index].PriorityQ,
				Weight:                    tp.UpstreamQueueAttributeList[index].Weight,
				DiscardPolicy:             tp.UpstreamQueueAttributeList[index].DiscardPolicy,
				DiscardConfig:             tp.UpstreamQueueAttributeList[index].DiscardConfig})
	}

	logger.Info(ctx, "length-of-downstream-gemport-attribute-list", len(tp.DownstreamQueueAttributeList))
	for index := 0; index < int(tp.NumGemPorts); index++ {
		dsQueueAttributeList = append(dsQueueAttributeList,
			&tp_pb.EPONQueueAttributes{GemportId: gemPorts[index],
				MaxQSize:         tp.DownstreamQueueAttributeList[index].MaxQSize,
				PbitMap:          tp.DownstreamQueueAttributeList[index].PbitMap,
				AesEncryption:    tp.DownstreamQueueAttributeList[index].AesEncryption,
				SchedulingPolicy: tp.DownstreamQueueAttributeList[index].SchedulingPolicy,
				PriorityQ:        tp.DownstreamQueueAttributeList[index].PriorityQ,
				Weight:           tp.DownstreamQueueAttributeList[index].Weight,
				DiscardPolicy:    tp.DownstreamQueueAttributeList[index].DiscardPolicy,
				DiscardConfig:    tp.DownstreamQueueAttributeList[index].DiscardConfig})
	}

	return &tp_pb.EponTechProfileInstance{
		SubscriberIdentifier:         uniPortName,
		Name:                         tp.Name,
		ProfileType:                  tp.ProfileType,
		Version:                      tp.Version,
		NumGemPorts:                  tp.NumGemPorts,
		InstanceControl:              tp.InstanceControl,
		PackageType:                  tp.PackageType,
		AllocId:                      tcontIDs[0],
		UpstreamQueueAttributeList:   usQueueAttributeList,
		DownstreamQueueAttributeList: dsQueueAttributeList}
}

// getSingleInstanceTp returns another TpInstance (GPON, XGPON, XGS-PON) for an ONU on a different
// uni port for the same TP ID, if it finds one, else nil.
func (t *TechProfileMgr) getSingleInstanceTp(ctx context.Context, tpPathSuffix string) *tp_pb.TechProfileInstance {

	// For example:
	// tpPathSuffix like "XGS-PON/64/olt-{1234}/pon-{0}/onu-{1}/uni-{1}"
	// is broken into ["XGS-PON/64/olt-{1234}/pon-{0}/onu-{1}" ""]
	uniPathSlice := regexp.MustCompile(`/uni-{[0-9]+}$`).Split(tpPathSuffix, 2)

	t.tpInstanceMapLock.RLock()
	defer t.tpInstanceMapLock.RUnlock()
	for i := 0; i < MaxUniPortPerOnu; i++ {
		key := fmt.Sprintf(uniPathSlice[0]+"/uni-{%d}", i)
		if tpInst, ok := t.tpInstanceMap[key]; ok {
			logger.Debugw(ctx, "found-single-instance-tp", log.Fields{"key": key})
			return tpInst
		}
	}
	return nil
}

// getSingleInstanceTp returns another TpInstance (EPON) for an ONU on a different
// uni port for the same TP ID, if it finds one, else nil.
func (t *TechProfileMgr) getSingleInstanceEponTp(ctx context.Context, tpPathSuffix string) *tp_pb.EponTechProfileInstance {
	// For example:
	// tpPathSuffix like "EPON/64/olt-{1234}/pon-{0}/onu-{1}/uni-{1}"
	// is broken into ["EPON/64/-{1234}/pon-{0}/onu-{1}" ""]
	uniPathSlice := regexp.MustCompile(`/uni-{[0-9]+}$`).Split(tpPathSuffix, 2)

	t.epontpInstanceMapLock.RLock()
	defer t.epontpInstanceMapLock.RUnlock()
	for i := 0; i < MaxUniPortPerOnu; i++ {
		key := fmt.Sprintf(uniPathSlice[0]+"/uni-{%d}", i)
		if tpInst, ok := t.eponTpInstanceMap[key]; ok {
			logger.Debugw(ctx, "found-single-instance-tp", log.Fields{"key": key})
			return tpInst
		}
	}
	return nil
}

// getDefaultTechProfile returns a default TechProfile for GPON, XGPON, XGS-PON
func (t *TechProfileMgr) getDefaultTechProfile(ctx context.Context) *tp_pb.TechProfile {
	var usGemPortAttributeList []*tp_pb.GemPortAttributes
	var dsGemPortAttributeList []*tp_pb.GemPortAttributes

	for _, pbit := range t.config.DefaultPbits {
		logger.Debugw(ctx, "creating-gem-port-profile-profile", log.Fields{"pbit": pbit})
		usGemPortAttributeList = append(usGemPortAttributeList,
			&tp_pb.GemPortAttributes{
				MaxQSize:         defaultMaxQueueSize,
				PbitMap:          pbit,
				AesEncryption:    defaultAESEncryption,
				SchedulingPolicy: tp_pb.SchedulingPolicy_WRR,
				PriorityQ:        defaultPriorityQueue,
				Weight:           defaultQueueWeight,
				DiscardPolicy:    tp_pb.DiscardPolicy_TailDrop,
				DiscardConfigV2: &tp_pb.DiscardConfig{
					DiscardPolicy: tp_pb.DiscardPolicy_Red,
					DiscardConfig: &tp_pb.DiscardConfig_RedDiscardConfig{
						RedDiscardConfig: &tp_pb.RedDiscardConfig{
							MinThreshold:   defaultMinThreshold,
							MaxThreshold:   defaultMaxThreshold,
							MaxProbability: defaultMaxProbability,
						},
					},
				},
				DiscardConfig: &tp_pb.RedDiscardConfig{
					MinThreshold:   defaultMinThreshold,
					MaxThreshold:   defaultMaxThreshold,
					MaxProbability: defaultMaxProbability,
				},
			})
		dsGemPortAttributeList = append(dsGemPortAttributeList,
			&tp_pb.GemPortAttributes{
				MaxQSize:         defaultMaxQueueSize,
				PbitMap:          pbit,
				AesEncryption:    defaultAESEncryption,
				SchedulingPolicy: tp_pb.SchedulingPolicy_WRR,
				PriorityQ:        defaultPriorityQueue,
				Weight:           defaultQueueWeight,
				DiscardPolicy:    tp_pb.DiscardPolicy_TailDrop,
				DiscardConfigV2: &tp_pb.DiscardConfig{
					DiscardPolicy: tp_pb.DiscardPolicy_Red,
					DiscardConfig: &tp_pb.DiscardConfig_RedDiscardConfig{
						RedDiscardConfig: &tp_pb.RedDiscardConfig{
							MinThreshold:   defaultMinThreshold,
							MaxThreshold:   defaultMaxThreshold,
							MaxProbability: defaultMaxProbability,
						},
					},
				},
				DiscardConfig: &tp_pb.RedDiscardConfig{
					MinThreshold:   defaultMinThreshold,
					MaxThreshold:   defaultMaxThreshold,
					MaxProbability: defaultMaxProbability,
				},
				IsMulticast:              defaultIsMulticast,
				DynamicAccessControlList: defaultAccessControlList,
				StaticAccessControlList:  defaultAccessControlList,
				MulticastGemId:           defaultMcastGemID})
	}
	return &tp_pb.TechProfile{
		Name:        t.config.DefaultTPName,
		ProfileType: t.resourceMgr.GetTechnology(),
		Version:     t.config.TPVersion,
		NumGemPorts: uint32(len(usGemPortAttributeList)),
		InstanceControl: &tp_pb.InstanceControl{
			Onu:               defaultOnuInstance,
			Uni:               defaultUniInstance,
			MaxGemPayloadSize: defaultGemPayloadSize},
		UsScheduler: &tp_pb.SchedulerAttributes{
			Direction:    tp_pb.Direction_UPSTREAM,
			AdditionalBw: tp_pb.AdditionalBW_AdditionalBW_BestEffort,
			Priority:     defaultPriority,
			Weight:       defaultWeight,
			QSchedPolicy: tp_pb.SchedulingPolicy_Hybrid},
		DsScheduler: &tp_pb.SchedulerAttributes{
			Direction:    tp_pb.Direction_DOWNSTREAM,
			AdditionalBw: tp_pb.AdditionalBW_AdditionalBW_BestEffort,
			Priority:     defaultPriority,
			Weight:       defaultWeight,
			QSchedPolicy: tp_pb.SchedulingPolicy_Hybrid},
		UpstreamGemPortAttributeList:   usGemPortAttributeList,
		DownstreamGemPortAttributeList: dsGemPortAttributeList}
}

// getDefaultEponProfile returns a default TechProfile for EPON
func (t *TechProfileMgr) getDefaultEponProfile(ctx context.Context) *tp_pb.EponTechProfile {

	var usQueueAttributeList []*tp_pb.EPONQueueAttributes
	var dsQueueAttributeList []*tp_pb.EPONQueueAttributes

	for _, pbit := range t.config.DefaultPbits {
		logger.Debugw(ctx, "Creating Queue", log.Fields{"pbit": pbit})
		usQueueAttributeList = append(usQueueAttributeList,
			&tp_pb.EPONQueueAttributes{
				MaxQSize:                  defaultMaxQueueSize,
				PbitMap:                   pbit,
				AesEncryption:             defaultAESEncryption,
				TrafficType:               defaultTrafficType,
				UnsolicitedGrantSize:      defaultUnsolicitedGrantSize,
				NominalInterval:           defaultNominalInterval,
				ToleratedPollJitter:       defaultToleratedPollJitter,
				RequestTransmissionPolicy: defaultRequestTransmissionPolicy,
				NumQSets:                  defaultNumQueueSet,
				QThresholds: &tp_pb.QThresholds{
					QThreshold1: defaultQThreshold1,
					QThreshold2: defaultQThreshold2,
					QThreshold3: defaultQThreshold3,
					QThreshold4: defaultQThreshold4,
					QThreshold5: defaultQThreshold5,
					QThreshold6: defaultQThreshold6,
					QThreshold7: defaultQThreshold7},
				SchedulingPolicy: tp_pb.SchedulingPolicy_WRR,
				PriorityQ:        defaultPriorityQueue,
				Weight:           defaultQueueWeight,
				DiscardPolicy:    tp_pb.DiscardPolicy_TailDrop,
				DiscardConfigV2: &tp_pb.DiscardConfig{
					DiscardPolicy: tp_pb.DiscardPolicy_Red,
					DiscardConfig: &tp_pb.DiscardConfig_RedDiscardConfig{
						RedDiscardConfig: &tp_pb.RedDiscardConfig{
							MinThreshold:   defaultMinThreshold,
							MaxThreshold:   defaultMaxThreshold,
							MaxProbability: defaultMaxProbability,
						},
					},
				},
				DiscardConfig: &tp_pb.RedDiscardConfig{
					MinThreshold:   defaultMinThreshold,
					MaxThreshold:   defaultMaxThreshold,
					MaxProbability: defaultMaxProbability,
				}})
		dsQueueAttributeList = append(dsQueueAttributeList,
			&tp_pb.EPONQueueAttributes{
				MaxQSize:         defaultMaxQueueSize,
				PbitMap:          pbit,
				AesEncryption:    defaultAESEncryption,
				SchedulingPolicy: tp_pb.SchedulingPolicy_WRR,
				PriorityQ:        defaultPriorityQueue,
				Weight:           defaultQueueWeight,
				DiscardPolicy:    tp_pb.DiscardPolicy_TailDrop,
				DiscardConfigV2: &tp_pb.DiscardConfig{
					DiscardPolicy: tp_pb.DiscardPolicy_Red,
					DiscardConfig: &tp_pb.DiscardConfig_RedDiscardConfig{
						RedDiscardConfig: &tp_pb.RedDiscardConfig{
							MinThreshold:   defaultMinThreshold,
							MaxThreshold:   defaultMaxThreshold,
							MaxProbability: defaultMaxProbability,
						},
					},
				},
				DiscardConfig: &tp_pb.RedDiscardConfig{
					MinThreshold:   defaultMinThreshold,
					MaxThreshold:   defaultMaxThreshold,
					MaxProbability: defaultMaxProbability,
				}})
	}
	return &tp_pb.EponTechProfile{
		Name:        t.config.DefaultTPName,
		ProfileType: t.resourceMgr.GetTechnology(),
		Version:     t.config.TPVersion,
		NumGemPorts: uint32(len(usQueueAttributeList)),
		InstanceControl: &tp_pb.InstanceControl{
			Onu:               defaultOnuInstance,
			Uni:               defaultUniInstance,
			MaxGemPayloadSize: defaultGemPayloadSize},
		PackageType:                  defaultPakageType,
		UpstreamQueueAttributeList:   usQueueAttributeList,
		DownstreamQueueAttributeList: dsQueueAttributeList}
}

// isMulticastGem returns true if isMulticast attribute value of a GEM port is true; false otherwise
func isMulticastGem(isMulticastAttrValue string) bool {
	return isMulticastAttrValue != "" &&
		(isMulticastAttrValue == "True" || isMulticastAttrValue == "true" || isMulticastAttrValue == "TRUE")
}

func (t *TechProfileMgr) addResourceInstanceToKVStore(ctx context.Context, tpID uint32, uniPortName string, resInst tp_pb.ResourceInstance) error {
	logger.Debugw(ctx, "adding-resource-instance-to-kv-store", log.Fields{"tpID": tpID, "uniPortName": uniPortName, "resInst": resInst})
	val, err := proto.Marshal(&resInst)
	if err != nil {
		logger.Errorw(ctx, "failed-to-marshall-resource-instance", log.Fields{"err": err, "tpID": tpID, "uniPortName": uniPortName, "resInst": resInst})
		return err
	}
	err = t.config.ResourceInstanceKVBacked.Put(ctx, fmt.Sprintf("%s/%d/%s", t.resourceMgr.GetTechnology(), tpID, uniPortName), val)
	return err
}

func (t *TechProfileMgr) removeResourceInstanceFromKVStore(ctx context.Context, tpID uint32, uniPortName string) error {
	logger.Debugw(ctx, "removing-resource-instance-to-kv-store", log.Fields{"tpID": tpID, "uniPortName": uniPortName})
	if err := t.config.ResourceInstanceKVBacked.Delete(ctx, fmt.Sprintf("%s/%d/%s", t.resourceMgr.GetTechnology(), tpID, uniPortName)); err != nil {
		logger.Errorw(ctx, "error-removing-resource-instance-to-kv-store", log.Fields{"err": err, "tpID": tpID, "uniPortName": uniPortName})
		return err
	}
	return nil
}

func (t *TechProfileMgr) getTPFromKVStore(ctx context.Context, tpID uint32) *tp_pb.TechProfile {
	var tp *tp_pb.TechProfile
	t.tpMapLock.RLock()
	tp, ok := t.tpMap[tpID]
	t.tpMapLock.RUnlock()
	if ok {
		logger.Debugw(ctx, "found-tp-in-cache", log.Fields{"tpID": tpID})
		return tp
	}
	key := fmt.Sprintf(t.config.TPFileKVPath, t.resourceMgr.GetTechnology(), tpID)
	logger.Debugw(ctx, "getting-tp-from-kv-store", log.Fields{"tpID": tpID, "Key": key})
	kvresult, err := t.config.DefaultTpKVBackend.Get(ctx, key)
	if err != nil {
		logger.Errorw(ctx, "error-fetching-from-kv-store", log.Fields{"err": err, "key": key})
		return nil
	}
	if kvresult != nil {
		/* Backend will return Value in string format,needs to be converted to []byte before unmarshal*/
		if value, err := kvstore.ToByte(kvresult.Value); err == nil {
			lTp := &tp_pb.TechProfile{}
			reader := bytes.NewReader(value)
			if err = jsonpb.Unmarshal(reader, lTp); err != nil {
				logger.Errorw(ctx, "error-unmarshalling-tp-from-kv-store", log.Fields{"err": err, "tpID": tpID, "error": err})
				return nil
			}

			logger.Debugw(ctx, "success-fetched-tp-from-kv-store", log.Fields{"tpID": tpID, "value": *lTp})
			return lTp
		} else {
			logger.Errorw(ctx, "error-decoding-tp", log.Fields{"err": err, "tpID": tpID})
			// We we create a default profile in this case.
		}
	}

	return nil
}

func (t *TechProfileMgr) getEponTPFromKVStore(ctx context.Context, tpID uint32) *tp_pb.EponTechProfile {
	var eponTp *tp_pb.EponTechProfile
	t.eponTpMapLock.RLock()
	eponTp, ok := t.eponTpMap[tpID]
	t.eponTpMapLock.RUnlock()
	if ok {
		logger.Debugw(ctx, "found-tp-in-cache", log.Fields{"tpID": tpID})
		return eponTp
	}
	key := fmt.Sprintf(t.config.TPFileKVPath, t.resourceMgr.GetTechnology(), tpID)
	logger.Debugw(ctx, "getting-epon-tp-from-kv-store", log.Fields{"tpID": tpID, "Key": key})
	kvresult, err := t.config.DefaultTpKVBackend.Get(ctx, key)
	if err != nil {
		logger.Errorw(ctx, "error-fetching-from-kv-store", log.Fields{"err": err, "key": key})
		return nil
	}
	if kvresult != nil {
		/* Backend will return Value in string format,needs to be converted to []byte before unmarshal*/
		if value, err := kvstore.ToByte(kvresult.Value); err == nil {
			lEponTp := &tp_pb.EponTechProfile{}
			reader := bytes.NewReader(value)
			if err = jsonpb.Unmarshal(reader, lEponTp); err != nil {
				logger.Errorw(ctx, "error-unmarshalling-epon-tp-from-kv-store", log.Fields{"err": err, "tpID": tpID, "error": err})
				return nil
			}

			logger.Debugw(ctx, "success-fetching-epon-tp-from-kv-store", log.Fields{"tpID": tpID, "value": *lEponTp})
			return lEponTp
		}
	}
	return nil
}

func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {

	logger.Infow(ctx, "kv-store", log.Fields{"storeType": storeType, "address": address})
	switch storeType {
	case "etcd":
		return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
	case "redis":
		return kvstore.NewRedisClient(address, timeout, false)
	case "redis-sentinel":
		return kvstore.NewRedisClient(address, timeout, true)
	}

	return nil, errors.New("unsupported-kv-store")
}

// buildTpInstanceFromResourceInstance for GPON, XGPON and XGS-PON technology - build TpInstance from TechProfile template and ResourceInstance
func (t *TechProfileMgr) buildTpInstanceFromResourceInstance(ctx context.Context, tp *tp_pb.TechProfile, resInst *tp_pb.ResourceInstance) *tp_pb.TechProfileInstance {

	if len(resInst.GemportIds) != int(tp.NumGemPorts) {
		logger.Errorw(ctx, "mismatch-in-number-of-gemports-between-template-and-resource-instance",
			log.Fields{"tpID": resInst.TpId, "totalResInstGemPortIDs": len(resInst.GemportIds), "totalTpTemplateGemPorts": tp.NumGemPorts})
		return nil
	}

	usGemPortAttributeList := make([]*tp_pb.GemPortAttributes, 0, tp.NumGemPorts)
	dsGemPortAttributeList := make([]*tp_pb.GemPortAttributes, 0, tp.NumGemPorts)
	dsMulticastGemAttributeList := make([]*tp_pb.GemPortAttributes, 0)
	dsUnicastGemAttributeList := make([]*tp_pb.GemPortAttributes, 0)

	logger.Debugw(ctx, "Building TP Instance",
		log.Fields{"tpID": resInst.TpId, "totalResInstGemPortIDs": len(resInst.GemportIds), "totalTpTemplateGemPorts": tp.NumGemPorts})

	usGemPortAttributeList = t.buildUpstreamGemPortAttributes(ctx, tp, resInst, usGemPortAttributeList)
	dsUnicastGemAttributeList, dsMulticastGemAttributeList = t.separateDownstreamGemPortAttributes(ctx, tp, dsUnicastGemAttributeList, dsMulticastGemAttributeList)
	dsGemPortAttributeList = t.buildDownstreamGemPortAttributes(ctx, tp, resInst, dsUnicastGemAttributeList, dsMulticastGemAttributeList, dsGemPortAttributeList)

	return &tp_pb.TechProfileInstance{
		SubscriberIdentifier: resInst.SubscriberIdentifier,
		Name:                 tp.Name,
		ProfileType:          tp.ProfileType,
		Version:              tp.Version,
		NumGemPorts:          tp.NumGemPorts,
		InstanceControl:      tp.InstanceControl,
		UsScheduler: &tp_pb.SchedulerAttributes{
			AllocId:      resInst.AllocId,
			Direction:    tp.UsScheduler.Direction,
			AdditionalBw: tp.UsScheduler.AdditionalBw,
			Priority:     tp.UsScheduler.Priority,
			Weight:       tp.UsScheduler.Weight,
			QSchedPolicy: tp.UsScheduler.QSchedPolicy},
		DsScheduler: &tp_pb.SchedulerAttributes{
			AllocId:      resInst.AllocId,
			Direction:    tp.DsScheduler.Direction,
			AdditionalBw: tp.DsScheduler.AdditionalBw,
			Priority:     tp.DsScheduler.Priority,
			Weight:       tp.DsScheduler.Weight,
			QSchedPolicy: tp.DsScheduler.QSchedPolicy},
		UpstreamGemPortAttributeList:   usGemPortAttributeList,
		DownstreamGemPortAttributeList: dsGemPortAttributeList}
}

// buildEponTpInstanceFromResourceInstance for EPON technology - build EponTpInstance from EponTechProfile template and ResourceInstance
func (t *TechProfileMgr) buildEponTpInstanceFromResourceInstance(ctx context.Context, tp *tp_pb.EponTechProfile, resInst *tp_pb.ResourceInstance) *tp_pb.EponTechProfileInstance {

	var usQueueAttributeList []*tp_pb.EPONQueueAttributes
	var dsQueueAttributeList []*tp_pb.EPONQueueAttributes

	if len(resInst.GemportIds) != int(tp.NumGemPorts) {
		logger.Errorw(ctx, "mismatch-in-number-of-gemports-between-epon-tp-template-and-resource-instance",
			log.Fields{"tpID": resInst.TpId, "totalResInstGemPortIDs": len(resInst.GemportIds), "totalTpTemplateGemPorts": tp.NumGemPorts})
		return nil
	}

	for index := 0; index < int(tp.NumGemPorts); index++ {
		usQueueAttributeList = append(usQueueAttributeList,
			&tp_pb.EPONQueueAttributes{GemportId: resInst.GemportIds[index],
				MaxQSize:                  tp.UpstreamQueueAttributeList[index].MaxQSize,
				PbitMap:                   tp.UpstreamQueueAttributeList[index].PbitMap,
				AesEncryption:             tp.UpstreamQueueAttributeList[index].AesEncryption,
				TrafficType:               tp.UpstreamQueueAttributeList[index].TrafficType,
				UnsolicitedGrantSize:      tp.UpstreamQueueAttributeList[index].UnsolicitedGrantSize,
				NominalInterval:           tp.UpstreamQueueAttributeList[index].NominalInterval,
				ToleratedPollJitter:       tp.UpstreamQueueAttributeList[index].ToleratedPollJitter,
				RequestTransmissionPolicy: tp.UpstreamQueueAttributeList[index].RequestTransmissionPolicy,
				NumQSets:                  tp.UpstreamQueueAttributeList[index].NumQSets,
				QThresholds:               tp.UpstreamQueueAttributeList[index].QThresholds,
				SchedulingPolicy:          tp.UpstreamQueueAttributeList[index].SchedulingPolicy,
				PriorityQ:                 tp.UpstreamQueueAttributeList[index].PriorityQ,
				Weight:                    tp.UpstreamQueueAttributeList[index].Weight,
				DiscardPolicy:             tp.UpstreamQueueAttributeList[index].DiscardPolicy,
				DiscardConfig:             tp.UpstreamQueueAttributeList[index].DiscardConfig})
	}

	for index := 0; index < int(tp.NumGemPorts); index++ {
		dsQueueAttributeList = append(dsQueueAttributeList,
			&tp_pb.EPONQueueAttributes{GemportId: resInst.GemportIds[index],
				MaxQSize:         tp.DownstreamQueueAttributeList[index].MaxQSize,
				PbitMap:          tp.DownstreamQueueAttributeList[index].PbitMap,
				AesEncryption:    tp.DownstreamQueueAttributeList[index].AesEncryption,
				SchedulingPolicy: tp.DownstreamQueueAttributeList[index].SchedulingPolicy,
				PriorityQ:        tp.DownstreamQueueAttributeList[index].PriorityQ,
				Weight:           tp.DownstreamQueueAttributeList[index].Weight,
				DiscardPolicy:    tp.DownstreamQueueAttributeList[index].DiscardPolicy,
				DiscardConfig:    tp.DownstreamQueueAttributeList[index].DiscardConfig})
	}

	return &tp_pb.EponTechProfileInstance{
		SubscriberIdentifier:         resInst.SubscriberIdentifier,
		Name:                         tp.Name,
		ProfileType:                  tp.ProfileType,
		Version:                      tp.Version,
		NumGemPorts:                  tp.NumGemPorts,
		InstanceControl:              tp.InstanceControl,
		PackageType:                  tp.PackageType,
		AllocId:                      resInst.AllocId,
		UpstreamQueueAttributeList:   usQueueAttributeList,
		DownstreamQueueAttributeList: dsQueueAttributeList}
}

func (t *TechProfileMgr) getTpInstanceFromResourceInstance(ctx context.Context, resInst *tp_pb.ResourceInstance) *tp_pb.TechProfileInstance {
	if resInst == nil {
		logger.Error(ctx, "resource-instance-nil")
		return nil
	}
	tp := t.getTPFromKVStore(ctx, resInst.TpId)
	if tp == nil {
		logger.Warnw(ctx, "tp-not-found-on-kv--creating-default-tp", log.Fields{"tpID": resInst.TpId})
		tp = t.getDefaultTechProfile(ctx)
	}
	return t.buildTpInstanceFromResourceInstance(ctx, tp, resInst)
}

func (t *TechProfileMgr) getEponTpInstanceFromResourceInstance(ctx context.Context, resInst *tp_pb.ResourceInstance) *tp_pb.EponTechProfileInstance {
	if resInst == nil {
		logger.Error(ctx, "resource-instance-nil")
		return nil
	}
	eponTp := t.getEponTPFromKVStore(ctx, resInst.TpId)
	if eponTp == nil {
		logger.Warnw(ctx, "tp-not-found-on-kv--creating-default-tp", log.Fields{"tpID": resInst.TpId})
		eponTp = t.getDefaultEponProfile(ctx)
	}
	return t.buildEponTpInstanceFromResourceInstance(ctx, eponTp, resInst)
}

func (t *TechProfileMgr) reconcileTpInstancesToCache(ctx context.Context, IntfId uint32, deviceId string) error {

	tech := t.resourceMgr.GetTechnology()
	newCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	//VOL-5417:Only reconcile the tech profiles for the subscribers associated with this PON port on this device.
	//Getting the list of supported tech profile IDs and then reconciling the tech profiles for these IDs associated
	//with the subscribers on this device  for this PON port.

	//Fetching the techprofile Keys  from the KV Store.
	tpkeys, _ := t.config.DefaultTpKVBackend.GetWithPrefixKeysOnly(ctx, tech)

	// Extract the techprofile Ids from the keys
	// The tpkeys will be of the format "service/voltha/technology_profiles/GPON/65"
	// where 65 is the techprofile Id
	tpIds := make([]uint32, 0)

	for _, key := range tpkeys {
		parts := strings.Split(key, "/")
		// Ensure the key has the expected format
		if len(parts) < 5 {
			logger.Errorw(ctx, "Key does not match expected format", log.Fields{"key": key})
			continue
		}
		// Convert the last part of the key to uint32 (techprofile Id)
		tpId, err := strconv.Atoi(parts[len(parts)-1])
		if err != nil {
			logger.Errorw(ctx, "Error converting techprofile Id to int", log.Fields{"key": key, "error": err})
			continue
		}
		tpIds = append(tpIds, uint32(tpId))
	}

	//for each tpid form a prefix and get the resource instance
	for _, tpId := range tpIds {
		prefix := fmt.Sprintf("%s/%d/olt-{%s}/pon-{%d}", tech, tpId, deviceId, IntfId)
		kvPairs, _ := t.config.ResourceInstanceKVBacked.GetWithPrefix(newCtx, prefix)
		//check if KvPairs is empty and if not then reconcile the techprofile instance
		if len(kvPairs) > 0 {
			for keyPath, kvPair := range kvPairs {
				if value, err := kvstore.ToByte(kvPair.Value); err == nil {
					var resInst tp_pb.ResourceInstance
					if err = proto.Unmarshal(value, &resInst); err != nil {
						logger.Errorw(ctx, "error-unmarshal-kv-pair", log.Fields{"err": err, "keyPath": keyPath, "value": value})
						continue
					} else {
						if tech == xgspon || tech == xgpon || tech == gpon {
							if tpInst := t.getTpInstanceFromResourceInstance(ctx, &resInst); tpInst != nil {
								keySuffixSlice := regexp.MustCompile(t.config.ResourceInstanceKVPathPrefix+"/").Split(keyPath, 2)
								if len(keySuffixSlice) == 2 {
									keySuffixFormatRegexp := regexp.MustCompile(`^[a-zA-Z\-]+/[0-9]+/olt-{[a-z0-9\-]+}/pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}$`)
									if !keySuffixFormatRegexp.Match([]byte(keySuffixSlice[1])) {
										logger.Errorw(ctx, "kv-path-not-confirming-to-format", log.Fields{"kvPath": keySuffixSlice[1]})
										continue
									}
								} else {
									logger.Errorw(ctx, "kv-instance-key-path-not-in-the-expected-format", log.Fields{"kvPath": keyPath})
									continue
								}
								t.tpInstanceMapLock.Lock()
								t.tpInstanceMap[keySuffixSlice[1]] = tpInst
								t.tpInstanceMapLock.Unlock()
								logger.Infow(ctx, "reconciled-tp-success", log.Fields{"keyPath": keyPath})
							}
						} else if tech == epon {
							if eponTpInst := t.getEponTpInstanceFromResourceInstance(ctx, &resInst); eponTpInst != nil {
								keySuffixSlice := regexp.MustCompile(t.config.ResourceInstanceKVPathPrefix+"/").Split(keyPath, 2)
								if len(keySuffixSlice) == 2 {
									keySuffixFormatRegexp := regexp.MustCompile(`^[a-zA-Z\-]+/[0-9]+/olt-{[a-z0-9\-]+}/pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}$`)
									if !keySuffixFormatRegexp.Match([]byte(keySuffixSlice[1])) {
										logger.Errorw(ctx, "kv-path-not-confirming-to-format", log.Fields{"kvPath": keySuffixSlice[1]})
										continue
									}
								} else {
									logger.Errorw(ctx, "kv-instance-key-path-not-in-the-expected-format", log.Fields{"kvPath": keyPath})
									continue
								}
								t.epontpInstanceMapLock.Lock()
								t.eponTpInstanceMap[keySuffixSlice[1]] = eponTpInst
								t.epontpInstanceMapLock.Unlock()
								logger.Debugw(ctx, "reconciled-epon-tp-success", log.Fields{"keyPath": keyPath})
							}
						} else {
							logger.Errorw(ctx, "unknown-tech", log.Fields{"tech": tech})
							return fmt.Errorf("unknown-tech-%v", tech)
						}
					}
				} else {
					logger.Errorw(ctx, "error-converting-kv-pair-value-to-byte", log.Fields{"err": err})
				}

			}

			return nil
		}
	}
	return nil
}

func (t *TechProfileMgr) buildUpstreamGemPortAttributes(ctx context.Context, tp *tp_pb.TechProfile, resInst *tp_pb.ResourceInstance, usGemPortAttributeList []*tp_pb.GemPortAttributes) []*tp_pb.GemPortAttributes {
	for index := 0; index < int(tp.NumGemPorts); index++ {
		usGemPortAttributeList = append(usGemPortAttributeList, &tp_pb.GemPortAttributes{
			GemportId:        resInst.GemportIds[index],
			MaxQSize:         tp.UpstreamGemPortAttributeList[index].MaxQSize,
			PbitMap:          tp.UpstreamGemPortAttributeList[index].PbitMap,
			AesEncryption:    tp.UpstreamGemPortAttributeList[index].AesEncryption,
			SchedulingPolicy: tp.UpstreamGemPortAttributeList[index].SchedulingPolicy,
			PriorityQ:        tp.UpstreamGemPortAttributeList[index].PriorityQ,
			Weight:           tp.UpstreamGemPortAttributeList[index].Weight,
			DiscardPolicy:    tp.UpstreamGemPortAttributeList[index].DiscardPolicy,
			DiscardConfig:    tp.UpstreamGemPortAttributeList[index].DiscardConfig,
		})
	}
	logger.Debugw(ctx, "Processed upstream GEM port attributes", log.Fields{"count": len(usGemPortAttributeList)})
	return usGemPortAttributeList
}

func (t *TechProfileMgr) separateDownstreamGemPortAttributes(ctx context.Context, tp *tp_pb.TechProfile, dsUnicastGemAttributeList, dsMulticastGemAttributeList []*tp_pb.GemPortAttributes) ([]*tp_pb.GemPortAttributes, []*tp_pb.GemPortAttributes) {
	for _, attr := range tp.DownstreamGemPortAttributeList {
		if isMulticastGem(attr.IsMulticast) {
			dsMulticastGemAttributeList = append(dsMulticastGemAttributeList, &tp_pb.GemPortAttributes{
				MulticastGemId:           attr.MulticastGemId,
				MaxQSize:                 attr.MaxQSize,
				PbitMap:                  attr.PbitMap,
				AesEncryption:            attr.AesEncryption,
				SchedulingPolicy:         attr.SchedulingPolicy,
				PriorityQ:                attr.PriorityQ,
				Weight:                   attr.Weight,
				DiscardPolicy:            attr.DiscardPolicy,
				DiscardConfig:            attr.DiscardConfig,
				IsMulticast:              attr.IsMulticast,
				DynamicAccessControlList: attr.DynamicAccessControlList,
				StaticAccessControlList:  attr.StaticAccessControlList,
			})
		} else {
			dsUnicastGemAttributeList = append(dsUnicastGemAttributeList, &tp_pb.GemPortAttributes{
				MaxQSize:         attr.MaxQSize,
				PbitMap:          attr.PbitMap,
				AesEncryption:    attr.AesEncryption,
				SchedulingPolicy: attr.SchedulingPolicy,
				PriorityQ:        attr.PriorityQ,
				Weight:           attr.Weight,
				DiscardPolicy:    attr.DiscardPolicy,
				DiscardConfig:    attr.DiscardConfig,
			})
		}
	}
	logger.Debugw(ctx, "Processed downstream GEM port attributes", log.Fields{
		"unicastCount": len(dsUnicastGemAttributeList), "multicastCount": len(dsMulticastGemAttributeList)})
	return dsUnicastGemAttributeList, dsMulticastGemAttributeList
}

func (t *TechProfileMgr) buildDownstreamGemPortAttributes(ctx context.Context, tp *tp_pb.TechProfile, resInst *tp_pb.ResourceInstance, dsUnicastGemAttributeList, dsMulticastGemAttributeList, dsGemPortAttributeList []*tp_pb.GemPortAttributes) []*tp_pb.GemPortAttributes {
	for index := 0; index < int(tp.NumGemPorts) && index < len(dsUnicastGemAttributeList); index++ {
		dsGemPortAttributeList = append(dsGemPortAttributeList, &tp_pb.GemPortAttributes{
			GemportId:        resInst.GemportIds[index],
			MaxQSize:         dsUnicastGemAttributeList[index].MaxQSize,
			PbitMap:          dsUnicastGemAttributeList[index].PbitMap,
			AesEncryption:    dsUnicastGemAttributeList[index].AesEncryption,
			SchedulingPolicy: dsUnicastGemAttributeList[index].SchedulingPolicy,
			PriorityQ:        dsUnicastGemAttributeList[index].PriorityQ,
			Weight:           dsUnicastGemAttributeList[index].Weight,
			DiscardPolicy:    dsUnicastGemAttributeList[index].DiscardPolicy,
			DiscardConfig:    dsUnicastGemAttributeList[index].DiscardConfig,
		})
	}
	dsGemPortAttributeList = append(dsGemPortAttributeList, dsMulticastGemAttributeList...)
	logger.Debugw(ctx, "Processed downstream GEM port attributes for final list", log.Fields{"count": len(dsGemPortAttributeList)})
	return dsGemPortAttributeList
}
