/*
 * Copyright 2020-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 mib provides the utilities for managing the onu mib
package mib

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"sync"
	"time"

	"github.com/looplab/fsm"
	"github.com/opencord/omci-lib-go"
	me "github.com/opencord/omci-lib-go/generated"
	"github.com/opencord/voltha-lib-go/v7/pkg/db"
	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
	vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"

	"github.com/opencord/voltha-lib-go/v7/pkg/log"

	cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
	devdb "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
	"github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
)

// events of MibUpload FSM
const (
	UlEvStart              = "UlEvStart"
	UlEvResetMib           = "UlEvResetMib"
	UlEvGetVendorAndSerial = "UlEvGetVendorAndSerial"
	UlEvGetEquipmentID     = "UlEvGetEquipmentId"
	UlEvGetFirstSwVersion  = "UlEvGetFirstSwVersion"
	UlEvGetSecondSwVersion = "UlEvGetSecondSwVersion"
	UlEvGetMacAddress      = "UlEvGetMacAddress"
	UlEvGetMibTemplate     = "UlEvGetMibTemplate"
	UlEvUploadMib          = "UlEvUploadMib"
	UlEvExamineMds         = "UlEvExamineMds"
	UlEvSuccess            = "UlEvSuccess"
	UlEvMismatch           = "UlEvMismatch"
	UlEvAuditMib           = "UlEvAuditMib"
	UlEvForceResync        = "UlEvForceResync"
	UlEvDiffsFound         = "UlEvDiffsFound"
	UlEvTimeout            = "UlEvTimeout"
	UlEvStop               = "UlEvStop"
)

// states of MibUpload FSM
const (
	UlStDisabled               = "UlStDisabled"
	UlStStarting               = "UlStStarting"
	UlStResettingMib           = "UlStResettingMib"
	UlStGettingVendorAndSerial = "UlStGettingVendorAndSerial"
	UlStGettingEquipmentID     = "UlStGettingEquipmentID"
	UlStGettingFirstSwVersion  = "UlStGettingFirstSwVersion"
	UlStGettingSecondSwVersion = "UlStGettingSecondSwVersion"
	UlStGettingMacAddress      = "UlStGettingMacAddress"
	UlStGettingMibTemplate     = "UlStGettingMibTemplate"
	UlStUploading              = "UlStUploading"
	UlStUploadDone             = "UlStUploadDone"
	UlStInSync                 = "UlStInSync"
	UlStExaminingMds           = "UlStExaminingMds"
	UlStResynchronizing        = "UlStResynchronizing"
	UlStExaminingMdsSuccess    = "UlStExaminingMdsSuccess"
	UlStAuditing               = "UlStAuditing"
	UlStReAuditing             = "UlStReAuditing"
	UlStOutOfSync              = "UlStOutOfSync"
)

// CMibUlFsmIdleState - TODO: add comment
const CMibUlFsmIdleState = UlStInSync

// events of MibDownload FSM
const (
	DlEvStart         = "DlEvStart"
	DlEvCreateGal     = "DlEvCreateGal"
	DlEvRxGalResp     = "DlEvRxGalResp"
	DlEvRxOnu2gResp   = "DlEvRxOnu2gResp"
	DlEvRxBridgeResp  = "DlEvRxBridgeResp"
	DlEvTimeoutSimple = "DlEvTimeoutSimple"
	DlEvTimeoutBridge = "DlEvTimeoutBridge"
	DlEvReset         = "DlEvReset"
	DlEvRestart       = "DlEvRestart"
)

// states of MibDownload FSM
const (
	DlStDisabled     = "DlStDisabled"
	DlStStarting     = "DlStStarting"
	DlStCreatingGal  = "DlStCreatingGal"
	DlStSettingOnu2g = "DlStSettingOnu2g"
	DlStBridgeInit   = "DlStBridgeInit"
	DlStDownloaded   = "DlStDownloaded"
	DlStResetting    = "DlStResetting"
)

// CMibDlFsmIdleState - TODO: add comment
const CMibDlFsmIdleState = DlStDisabled

const (
	// NOTE that this hardcoded to service/voltha as the MIB template is shared across stacks
	cBasePathMibTemplateKvStore = "service/voltha/omci_mibs/go_templates"
	cSuffixMibTemplateKvStore   = "%s/%s/%s"
	cBasePathOnuKVStore         = "%s/openonu"
)

const cEmptyMacAddrString = "000000000000"
const cEmptySerialNumberString = "0000000000000000"

type uniPersConfig struct {
	PersUniID      uint8                   `json:"uni_id"`
	PersTpPathMap  map[uint8]string        `json:"PersTpPathMap"` // tp-id to tp-path map
	PersFlowParams []cmn.UniVlanFlowParams `json:"flow_params"`   //as defined in omci_ani_config.go
}

type onuPersistentData struct {
	PersOnuID              uint32            `json:"onu_id"`
	PersIntfID             uint32            `json:"intf_id"`
	PersSerialNumber       string            `json:"serial_number"`
	PersMacAddress         string            `json:"mac_address"`
	PersVendorID           string            `json:"vendor_id"`
	PersEquipmentID        string            `json:"equipment_id"`
	PersActiveSwVersion    string            `json:"active_sw_version"`
	PersAdminState         string            `json:"admin_state"`
	PersOperState          string            `json:"oper_state"`
	PersUniUnlockDone      bool              `json:"uni_unlock_done"`
	PersUniDisableDone     bool              `json:"uni_disable_done"`
	PersMibAuditInterval   time.Duration     `json:"mib_audit_interval"`
	PersMibLastDbSync      uint32            `json:"mib_last_db_sync"`
	PersMibDataSyncAdpt    uint8             `json:"mib_data_sync_adpt"`
	PersUniConfig          []uniPersConfig   `json:"uni_config"`
	PersAlarmAuditInterval time.Duration     `json:"alarm_audit_interval"`
	PersTcontMap           map[uint16]uint16 `json:"tcont_map"` //alloc-id to me-instance-id map
}

// OnuDeviceEntry - ONU device info and FSM events.
type OnuDeviceEntry struct {
	deviceID                   string
	baseDeviceHandler          cmn.IdeviceHandler
	pOpenOnuAc                 cmn.IopenONUAC
	pOnuTP                     cmn.IonuUniTechProf
	coreClient                 *vgrpc.Client
	PDevOmciCC                 *cmn.OmciCC
	pOnuDB                     *devdb.OnuDeviceDB
	mibTemplateKVStore         *db.Backend
	MutexPersOnuConfig         sync.RWMutex
	SOnuPersistentData         onuPersistentData
	reconcilingFlows           bool
	mutexReconcilingFlowsFlag  sync.RWMutex
	chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
	mibTemplatePath            string
	mutexOnuKVStore            sync.RWMutex
	onuKVStore                 *db.Backend
	onuKVStorePath             string
	mutexOnuKVStoreProcResult  sync.RWMutex
	onuKVStoreProcResult       error //error indication of processing
	chOnuKvProcessingStep      chan uint8
	mutexOnuSwImageIndications sync.RWMutex
	onuSwImageIndications      cmn.SswImageIndications
	MutexOnuImageStatus        sync.RWMutex
	POnuImageStatus            *swupg.OnuImageStatus
	//lockDeviceEntries           sync.RWMutex
	mibDbClass    func(context.Context) error
	supportedFsms cmn.OmciDeviceFsms
	devState      cmn.OnuDeviceEvent
	// Audit and MDS
	mibAuditInterval   time.Duration
	alarmAuditInterval time.Duration
	// TODO: periodical mib resync will be implemented with story VOL-3792
	//mibNextDbResync uint32

	// for mibUpload
	PMibUploadFsm          *cmn.AdapterFsm //could be handled dynamically and more general as pcmn.AdapterFsm - perhaps later
	mutexLastTxParamStruct sync.RWMutex
	lastTxParamStruct      sLastTxMeParameter
	// for mibDownload
	PMibDownloadFsm *cmn.AdapterFsm //could be handled dynamically and more general as pcmn.AdapterFsm - perhaps later
	//remark: general usage of pAdapterFsm would require generalization of CommChan  usage and internal event setting
	//  within the FSM event procedures
	mutexPLastTxMeInstance           sync.RWMutex
	pLastTxMeInstance                *me.ManagedEntity
	omciMessageReceived              chan bool        //seperate channel needed by DownloadFsm
	omciRebootMessageReceivedChannel chan cmn.Message // channel needed by reboot request

	mutexTcontMap sync.RWMutex
}

//NewOnuDeviceEntry returns a new instance of a OnuDeviceEntry
//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
func NewOnuDeviceEntry(ctx context.Context, cc *vgrpc.Client, dh cmn.IdeviceHandler,
	openonu cmn.IopenONUAC) *OnuDeviceEntry {
	var onuDeviceEntry OnuDeviceEntry
	onuDeviceEntry.deviceID = dh.GetDeviceID()
	logger.Debugw(ctx, "init-onuDeviceEntry", log.Fields{"device-id": onuDeviceEntry.deviceID})
	onuDeviceEntry.baseDeviceHandler = dh
	onuDeviceEntry.pOpenOnuAc = openonu
	onuDeviceEntry.coreClient = cc
	onuDeviceEntry.devState = cmn.DeviceStatusInit
	onuDeviceEntry.SOnuPersistentData.PersUniConfig = make([]uniPersConfig, 0)
	onuDeviceEntry.SOnuPersistentData.PersTcontMap = make(map[uint16]uint16)
	onuDeviceEntry.chReconcilingFlowsFinished = make(chan bool)
	onuDeviceEntry.reconcilingFlows = false
	onuDeviceEntry.chOnuKvProcessingStep = make(chan uint8)
	onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan cmn.Message, 2048)
	//openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
	//OMCI related databases are on a per-agent basis. State machines and tasks
	//are per ONU Vendor
	//
	// MIB Synchronization Database - possible overloading from arguments
	supportedFsms := onuDeviceEntry.pOpenOnuAc.GetSupportedFsms()
	if supportedFsms != nil {
		onuDeviceEntry.supportedFsms = *supportedFsms
	} else {
		// This branch is currently not used and is for potential future usage of alternative MIB Sync FSMs only!
		//var mibSyncFsm = NewMibSynchronizer()
		// use some internal defaults, if not defined from outside
		onuDeviceEntry.supportedFsms = cmn.OmciDeviceFsms{
			"mib-synchronizer": {
				//mibSyncFsm,        // Implements the MIB synchronization state machine
				DatabaseClass: onuDeviceEntry.mibDbVolatileDict, // Implements volatile ME MIB database
				//true,                             // Advertise events on OpenOMCI event bus
				AuditInterval: dh.GetAlarmAuditInterval(), // Time to wait between MIB audits.  0 to disable audits.
				// map[string]func() error{
				// 	"mib-upload":    onuDeviceEntry.MibUploadTask,
				// 	"mib-template":  onuDeviceEntry.MibTemplateTask,
				// 	"get-mds":       onuDeviceEntry.GetMdsTask,
				// 	"mib-audit":     onuDeviceEntry.GetMdsTask,
				// 	"mib-resync":    onuDeviceEntry.MibResyncTask,
				// 	"mib-reconcile": onuDeviceEntry.MibReconcileTask,
				// },
			},
		}
	}
	onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].DatabaseClass
	logger.Debug(ctx, "access2mibDbClass")
	go onuDeviceEntry.mibDbClass(ctx)
	if !dh.IsReconciling() {
		onuDeviceEntry.mibAuditInterval = onuDeviceEntry.supportedFsms["mib-synchronizer"].AuditInterval
		onuDeviceEntry.SOnuPersistentData.PersMibAuditInterval = onuDeviceEntry.mibAuditInterval
		onuDeviceEntry.alarmAuditInterval = dh.GetAlarmAuditInterval()
		onuDeviceEntry.SOnuPersistentData.PersAlarmAuditInterval = onuDeviceEntry.alarmAuditInterval
	} else {
		logger.Debugw(ctx, "reconciling - take audit interval from persistent data", log.Fields{"device-id": onuDeviceEntry.deviceID})
		// TODO: This is a preparation for VOL-VOL-3811 to preserve config history in case of
		// vendor- or deviceID-specific configurations via voltctl-commands
		onuDeviceEntry.mibAuditInterval = onuDeviceEntry.SOnuPersistentData.PersMibAuditInterval
		onuDeviceEntry.alarmAuditInterval = onuDeviceEntry.SOnuPersistentData.PersAlarmAuditInterval
	}
	logger.Debugw(ctx, "MibAuditInterval and AlarmAuditInterval is set to", log.Fields{"mib-audit-interval": onuDeviceEntry.mibAuditInterval,
		"alarm-audit-interval": onuDeviceEntry.alarmAuditInterval})
	// TODO: periodical mib resync will be implemented with story VOL-3792
	//onuDeviceEntry.mibNextDbResync = 0

	// Omci related Mib upload sync state machine
	mibUploadChan := make(chan cmn.Message, 2048)
	onuDeviceEntry.PMibUploadFsm = cmn.NewAdapterFsm("MibUpload", onuDeviceEntry.deviceID, mibUploadChan)
	onuDeviceEntry.PMibUploadFsm.PFsm = fsm.NewFSM(
		UlStDisabled,
		fsm.Events{

			{Name: UlEvStart, Src: []string{UlStDisabled}, Dst: UlStStarting},

			{Name: UlEvResetMib, Src: []string{UlStStarting}, Dst: UlStResettingMib},
			{Name: UlEvGetVendorAndSerial, Src: []string{UlStResettingMib}, Dst: UlStGettingVendorAndSerial},
			{Name: UlEvGetEquipmentID, Src: []string{UlStGettingVendorAndSerial}, Dst: UlStGettingEquipmentID},
			{Name: UlEvGetFirstSwVersion, Src: []string{UlStGettingEquipmentID}, Dst: UlStGettingFirstSwVersion},
			{Name: UlEvGetSecondSwVersion, Src: []string{UlStGettingFirstSwVersion}, Dst: UlStGettingSecondSwVersion},
			{Name: UlEvGetMacAddress, Src: []string{UlStGettingSecondSwVersion}, Dst: UlStGettingMacAddress},
			{Name: UlEvGetMibTemplate, Src: []string{UlStGettingMacAddress}, Dst: UlStGettingMibTemplate},

			{Name: UlEvUploadMib, Src: []string{UlStGettingMibTemplate}, Dst: UlStUploading},
			{Name: UlEvExamineMds, Src: []string{UlStStarting}, Dst: UlStExaminingMds},

			{Name: UlEvSuccess, Src: []string{UlStGettingMibTemplate}, Dst: UlStUploadDone},
			{Name: UlEvSuccess, Src: []string{UlStUploading}, Dst: UlStUploadDone},

			{Name: UlEvSuccess, Src: []string{UlStUploadDone}, Dst: UlStInSync},
			//{Name: UlEvSuccess, Src: []string{UlStExaminingMds}, Dst: UlStInSync},
			{Name: UlEvSuccess, Src: []string{UlStExaminingMds}, Dst: UlStExaminingMdsSuccess},
			// TODO: As long as mib-resynchronizing is not implemented, failed MDS-examination triggers
			// mib-reset and new provisioning at this point
			//{Name: UlEvMismatch, Src: []string{UlStExaminingMds}, Dst: UlStResynchronizing},
			{Name: UlEvMismatch, Src: []string{UlStExaminingMds}, Dst: UlStResettingMib},

			{Name: UlEvSuccess, Src: []string{UlStExaminingMdsSuccess}, Dst: UlStInSync},
			{Name: UlEvMismatch, Src: []string{UlStExaminingMdsSuccess}, Dst: UlStResettingMib},

			{Name: UlEvAuditMib, Src: []string{UlStInSync}, Dst: UlStAuditing},

			{Name: UlEvSuccess, Src: []string{UlStOutOfSync}, Dst: UlStInSync},
			{Name: UlEvAuditMib, Src: []string{UlStOutOfSync}, Dst: UlStAuditing},

			{Name: UlEvSuccess, Src: []string{UlStAuditing}, Dst: UlStInSync},
			{Name: UlEvMismatch, Src: []string{UlStAuditing}, Dst: UlStReAuditing},
			{Name: UlEvForceResync, Src: []string{UlStAuditing}, Dst: UlStResynchronizing},

			{Name: UlEvSuccess, Src: []string{UlStReAuditing}, Dst: UlStInSync},
			{Name: UlEvMismatch, Src: []string{UlStReAuditing}, Dst: UlStResettingMib},

			{Name: UlEvSuccess, Src: []string{UlStResynchronizing}, Dst: UlStInSync},
			{Name: UlEvDiffsFound, Src: []string{UlStResynchronizing}, Dst: UlStOutOfSync},

			{Name: UlEvTimeout, Src: []string{UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingEquipmentID, UlStGettingFirstSwVersion,
				UlStGettingSecondSwVersion, UlStGettingMacAddress, UlStGettingMibTemplate, UlStUploading, UlStResynchronizing, UlStExaminingMds,
				UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStStarting},

			{Name: UlEvStop, Src: []string{UlStStarting, UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingEquipmentID, UlStGettingFirstSwVersion,
				UlStGettingSecondSwVersion, UlStGettingMacAddress, UlStGettingMibTemplate, UlStUploading, UlStResynchronizing, UlStExaminingMds,
				UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStDisabled},
		},

		fsm.Callbacks{
			"enter_state":                         func(e *fsm.Event) { onuDeviceEntry.PMibUploadFsm.LogFsmStateChange(ctx, e) },
			"enter_" + UlStStarting:               func(e *fsm.Event) { onuDeviceEntry.enterStartingState(ctx, e) },
			"enter_" + UlStResettingMib:           func(e *fsm.Event) { onuDeviceEntry.enterResettingMibState(ctx, e) },
			"enter_" + UlStGettingVendorAndSerial: func(e *fsm.Event) { onuDeviceEntry.enterGettingVendorAndSerialState(ctx, e) },
			"enter_" + UlStGettingEquipmentID:     func(e *fsm.Event) { onuDeviceEntry.enterGettingEquipmentIDState(ctx, e) },
			"enter_" + UlStGettingFirstSwVersion:  func(e *fsm.Event) { onuDeviceEntry.enterGettingFirstSwVersionState(ctx, e) },
			"enter_" + UlStGettingSecondSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingSecondSwVersionState(ctx, e) },
			"enter_" + UlStGettingMacAddress:      func(e *fsm.Event) { onuDeviceEntry.enterGettingMacAddressState(ctx, e) },
			"enter_" + UlStGettingMibTemplate:     func(e *fsm.Event) { onuDeviceEntry.enterGettingMibTemplateState(ctx, e) },
			"enter_" + UlStUploading:              func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(ctx, e) },
			"enter_" + UlStUploadDone:             func(e *fsm.Event) { onuDeviceEntry.enterUploadDoneState(ctx, e) },
			"enter_" + UlStExaminingMds:           func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(ctx, e) },
			"enter_" + UlStResynchronizing:        func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(ctx, e) },
			"enter_" + UlStExaminingMdsSuccess:    func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsSuccessState(ctx, e) },
			"enter_" + UlStAuditing:               func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(ctx, e) },
			"enter_" + UlStReAuditing:             func(e *fsm.Event) { onuDeviceEntry.enterReAuditingState(ctx, e) },
			"enter_" + UlStOutOfSync:              func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(ctx, e) },
			"enter_" + UlStInSync:                 func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(ctx, e) },
		},
	)
	// Omci related Mib download state machine
	mibDownloadChan := make(chan cmn.Message, 2048)
	onuDeviceEntry.PMibDownloadFsm = cmn.NewAdapterFsm("MibDownload", onuDeviceEntry.deviceID, mibDownloadChan)
	onuDeviceEntry.PMibDownloadFsm.PFsm = fsm.NewFSM(
		DlStDisabled,
		fsm.Events{

			{Name: DlEvStart, Src: []string{DlStDisabled}, Dst: DlStStarting},

			{Name: DlEvCreateGal, Src: []string{DlStStarting}, Dst: DlStCreatingGal},
			{Name: DlEvRxGalResp, Src: []string{DlStCreatingGal}, Dst: DlStSettingOnu2g},
			{Name: DlEvRxOnu2gResp, Src: []string{DlStSettingOnu2g}, Dst: DlStBridgeInit},
			// the bridge state is used for multi ME config for alle UNI related ports
			// maybe such could be reflected in the state machine as well (port number parametrized)
			// but that looks not straightforward here - so we keep it simple here for the beginning(?)
			{Name: DlEvRxBridgeResp, Src: []string{DlStBridgeInit}, Dst: DlStDownloaded},

			{Name: DlEvTimeoutSimple, Src: []string{DlStCreatingGal, DlStSettingOnu2g}, Dst: DlStStarting},
			{Name: DlEvTimeoutBridge, Src: []string{DlStBridgeInit}, Dst: DlStStarting},

			{Name: DlEvReset, Src: []string{DlStStarting, DlStCreatingGal, DlStSettingOnu2g,
				DlStBridgeInit, DlStDownloaded}, Dst: DlStResetting},
			// exceptional treatment for all states except DlStResetting
			{Name: DlEvRestart, Src: []string{DlStStarting, DlStCreatingGal, DlStSettingOnu2g,
				DlStBridgeInit, DlStDownloaded, DlStResetting}, Dst: DlStDisabled},
		},

		fsm.Callbacks{
			"enter_state":               func(e *fsm.Event) { onuDeviceEntry.PMibDownloadFsm.LogFsmStateChange(ctx, e) },
			"enter_" + DlStStarting:     func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(ctx, e) },
			"enter_" + DlStCreatingGal:  func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(ctx, e) },
			"enter_" + DlStSettingOnu2g: func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(ctx, e) },
			"enter_" + DlStBridgeInit:   func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(ctx, e) },
			"enter_" + DlStDownloaded:   func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(ctx, e) },
			"enter_" + DlStResetting:    func(e *fsm.Event) { onuDeviceEntry.enterResettingState(ctx, e) },
		},
	)
	if onuDeviceEntry.PMibDownloadFsm == nil || onuDeviceEntry.PMibDownloadFsm.PFsm == nil {
		logger.Errorw(ctx, "MibDownloadFsm could not be instantiated", log.Fields{"device-id": onuDeviceEntry.deviceID})
		// TODO some specific error treatment - or waiting for crash ?
	}

	onuDeviceEntry.mibTemplateKVStore = onuDeviceEntry.baseDeviceHandler.SetBackend(ctx, cBasePathMibTemplateKvStore)
	if onuDeviceEntry.mibTemplateKVStore == nil {
		logger.Errorw(ctx, "Can't access mibTemplateKVStore - no backend connection to service",
			log.Fields{"device-id": onuDeviceEntry.deviceID, "service": cBasePathMibTemplateKvStore})
	}

	onuDeviceEntry.onuKVStorePath = onuDeviceEntry.deviceID
	baseKvStorePath := fmt.Sprintf(cBasePathOnuKVStore, dh.GetBackendPathPrefix())
	onuDeviceEntry.onuKVStore = onuDeviceEntry.baseDeviceHandler.SetBackend(ctx, baseKvStorePath)
	if onuDeviceEntry.onuKVStore == nil {
		logger.Errorw(ctx, "Can't access onuKVStore - no backend connection to service",
			log.Fields{"device-id": onuDeviceEntry.deviceID, "service": baseKvStorePath})
	}

	// Alarm Synchronization Database

	//self._alarm_db = None
	//self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
	return &onuDeviceEntry
}

//Start starts (logs) the omci agent
func (oo *OnuDeviceEntry) Start(ctx context.Context) error {
	logger.Debugw(ctx, "OnuDeviceEntry-starting", log.Fields{"for device-id": oo.deviceID})
	if oo.PDevOmciCC == nil {
		oo.PDevOmciCC = cmn.NewOmciCC(ctx, oo.deviceID, oo.baseDeviceHandler, oo, oo.baseDeviceHandler.GetOnuAlarmManager(), oo.coreClient)
		if oo.PDevOmciCC == nil {
			logger.Errorw(ctx, "Could not create devOmciCc - abort", log.Fields{"for device-id": oo.deviceID})
			return fmt.Errorf("could not create devOmciCc %s", oo.deviceID)
		}
	}
	return nil
}

//Stop stops/resets the omciCC
func (oo *OnuDeviceEntry) Stop(ctx context.Context, abResetOmciCC bool) error {
	logger.Debugw(ctx, "OnuDeviceEntry-stopping", log.Fields{"for device-id": oo.deviceID})
	if abResetOmciCC && (oo.PDevOmciCC != nil) {
		_ = oo.PDevOmciCC.Stop(ctx)
	}
	//to allow for all event notifications again when re-using the device and omciCC
	oo.devState = cmn.DeviceStatusInit
	return nil
}

// Reboot - TODO: add comment
func (oo *OnuDeviceEntry) Reboot(ctx context.Context) error {
	logger.Debugw(ctx, "OnuDeviceEntry-rebooting", log.Fields{"for device-id": oo.deviceID})
	if oo.PDevOmciCC != nil {
		if err := oo.PDevOmciCC.SendReboot(ctx, oo.baseDeviceHandler.GetOmciTimeout(), true, oo.omciRebootMessageReceivedChannel); err != nil {
			logger.Errorw(ctx, "onu didn't reboot", log.Fields{"for device-id": oo.deviceID})
			return err
		}
	}
	return nil
}

// WaitForRebootResponse - TODO: add comment
func (oo *OnuDeviceEntry) WaitForRebootResponse(ctx context.Context, responseChannel chan cmn.Message) error {
	select {
	case <-time.After(oo.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
		logger.Warnw(ctx, "reboot timeout", log.Fields{"for device-id": oo.deviceID})
		return fmt.Errorf("rebootTimeout")
	case data := <-responseChannel:
		switch data.Data.(cmn.OmciMessage).OmciMsg.MessageType {
		case omci.RebootResponseType:
			{
				msgLayer := (*data.Data.(cmn.OmciMessage).OmciPacket).Layer(omci.LayerTypeRebootResponse)
				if msgLayer == nil {
					return fmt.Errorf("omci Msg layer could not be detected for RebootResponseType")
				}
				msgObj, msgOk := msgLayer.(*omci.RebootResponse)
				if !msgOk {
					return fmt.Errorf("omci Msg layer could not be assigned for RebootResponseType %s", oo.deviceID)
				}
				logger.Debugw(ctx, "RebootResponse data", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj})
				if msgObj.Result != me.Success {
					logger.Errorw(ctx, "Omci RebootResponse result error", log.Fields{"device-id": oo.deviceID, "Error": msgObj.Result})
					// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
					return fmt.Errorf("omci RebootResponse result error indication %s for device %s",
						msgObj.Result, oo.deviceID)
				}
				return nil
			}
		}
		logger.Warnw(ctx, "Reboot response message type error", log.Fields{"for device-id": oo.deviceID})
		return fmt.Errorf("unexpected OmciResponse type received %s", oo.deviceID)
	}
}

//Relay the InSync message via Handler to Rw core - Status update
func (oo *OnuDeviceEntry) transferSystemEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
	logger.Debugw(ctx, "relaying system-event", log.Fields{"Event": devEvent})
	// decouple the handler transfer from further processing here
	// TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
	if devEvent == cmn.MibDatabaseSync {
		if oo.devState < cmn.MibDatabaseSync { //devState has not been synced yet
			oo.devState = cmn.MibDatabaseSync
			go oo.baseDeviceHandler.DeviceProcStatusUpdate(ctx, devEvent)
			//TODO!!! device control: next step: start MIB capability verification from here ?!!!
		} else {
			logger.Debugw(ctx, "mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
		}
	} else if devEvent == cmn.MibDownloadDone {
		if oo.devState < cmn.MibDownloadDone { //devState has not been synced yet
			oo.devState = cmn.MibDownloadDone
			go oo.baseDeviceHandler.DeviceProcStatusUpdate(ctx, devEvent)
		} else {
			logger.Debugw(ctx, "mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
		}
	} else {
		logger.Warnw(ctx, "device-event not yet handled", log.Fields{"state": devEvent})
	}
}

// RestoreDataFromOnuKvStore - TODO: add comment
func (oo *OnuDeviceEntry) RestoreDataFromOnuKvStore(ctx context.Context) error {
	if oo.onuKVStore == nil {
		logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
		return fmt.Errorf(fmt.Sprintf("onuKVStore-not-set-abort-%s", oo.deviceID))
	}
	oo.MutexPersOnuConfig.Lock()
	defer oo.MutexPersOnuConfig.Unlock()
	oo.SOnuPersistentData =
		onuPersistentData{0, 0, "", "", "", "", "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
	oo.mutexOnuKVStore.RLock()
	Value, err := oo.onuKVStore.Get(ctx, oo.onuKVStorePath)
	oo.mutexOnuKVStore.RUnlock()
	if err == nil {
		if Value != nil {
			logger.Debugw(ctx, "ONU-data read",
				log.Fields{"Key": Value.Key, "device-id": oo.deviceID})
			tmpBytes, _ := kvstore.ToByte(Value.Value)

			if err = json.Unmarshal(tmpBytes, &oo.SOnuPersistentData); err != nil {
				logger.Errorw(ctx, "unable to unmarshal ONU-data", log.Fields{"error": err, "device-id": oo.deviceID})
				return fmt.Errorf(fmt.Sprintf("unable-to-unmarshal-ONU-data-%s", oo.deviceID))
			}
			logger.Debugw(ctx, "ONU-data", log.Fields{"SOnuPersistentData": oo.SOnuPersistentData,
				"device-id": oo.deviceID})
		} else {
			logger.Debugw(ctx, "no ONU-data found", log.Fields{"path": oo.onuKVStorePath, "device-id": oo.deviceID})
			return fmt.Errorf("no-ONU-data-found")
		}
	} else {
		logger.Errorw(ctx, "unable to read from KVstore", log.Fields{"device-id": oo.deviceID})
		return fmt.Errorf(fmt.Sprintf("unable-to-read-from-KVstore-%s", oo.deviceID))
	}
	return nil
}

// DeleteDataFromOnuKvStore - TODO: add comment
func (oo *OnuDeviceEntry) DeleteDataFromOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
	defer wg.Done()

	if oo.onuKVStore == nil {
		logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
		oo.setKvProcessingErrorIndication(errors.New("onu-data delete aborted: onuKVStore not set"))
		return
	}
	var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
	go oo.deletePersistentData(ctx, processingStep)
	if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
		//timeout or error detected
		logger.Debugw(ctx, "ONU-data not deleted - abort", log.Fields{"device-id": oo.deviceID})
		oo.setKvProcessingErrorIndication(errors.New("onu-data delete aborted: during kv-access"))
		return
	}
}

func (oo *OnuDeviceEntry) deletePersistentData(ctx context.Context, aProcessingStep uint8) {

	logger.Debugw(ctx, "delete and clear internal persistency data", log.Fields{"device-id": oo.deviceID})

	oo.MutexPersOnuConfig.Lock()
	defer oo.MutexPersOnuConfig.Unlock()

	oo.SOnuPersistentData.PersUniConfig = nil //releasing all UniConfig entries to garbage collector default entry
	oo.SOnuPersistentData =
		onuPersistentData{0, 0, "", "", "", "", "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
	logger.Debugw(ctx, "delete ONU-data from KVStore", log.Fields{"device-id": oo.deviceID})
	oo.mutexOnuKVStore.Lock()
	err := oo.onuKVStore.Delete(ctx, oo.onuKVStorePath)
	oo.mutexOnuKVStore.Unlock()
	if err != nil {
		logger.Errorw(ctx, "unable to delete in KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
		oo.chOnuKvProcessingStep <- 0 //error indication
		return
	}
	oo.chOnuKvProcessingStep <- aProcessingStep //done
}

// UpdateOnuKvStore - TODO: add comment
func (oo *OnuDeviceEntry) UpdateOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
	defer wg.Done()

	if oo.onuKVStore == nil {
		logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
		oo.setKvProcessingErrorIndication(errors.New("onu-data update aborted: onuKVStore not set"))
		return
	}
	var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
	go oo.storeDataInOnuKvStore(ctx, processingStep)
	if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
		//timeout or error detected
		logger.Debugw(ctx, "ONU-data not written - abort", log.Fields{"device-id": oo.deviceID})
		oo.setKvProcessingErrorIndication(errors.New("onu-data update aborted: during writing process"))
		return
	}
}

func (oo *OnuDeviceEntry) storeDataInOnuKvStore(ctx context.Context, aProcessingStep uint8) {

	oo.MutexPersOnuConfig.Lock()
	defer oo.MutexPersOnuConfig.Unlock()
	//assign values which are not already present when NewOnuDeviceEntry() is called
	onuIndication := oo.baseDeviceHandler.GetOnuIndication()
	oo.SOnuPersistentData.PersOnuID = onuIndication.OnuId
	oo.SOnuPersistentData.PersIntfID = onuIndication.IntfId
	//TODO: verify usage of these values during restart UC
	oo.SOnuPersistentData.PersAdminState = onuIndication.AdminState
	oo.SOnuPersistentData.PersOperState = onuIndication.OperState

	logger.Debugw(ctx, "Update ONU-data in KVStore", log.Fields{"device-id": oo.deviceID, "SOnuPersistentData": oo.SOnuPersistentData})

	Value, err := json.Marshal(oo.SOnuPersistentData)
	if err != nil {
		logger.Errorw(ctx, "unable to marshal ONU-data", log.Fields{"SOnuPersistentData": oo.SOnuPersistentData,
			"device-id": oo.deviceID, "err": err})
		oo.chOnuKvProcessingStep <- 0 //error indication
		return
	}
	oo.pOpenOnuAc.RLockMutexDeviceHandlersMap()
	if _, exist := oo.pOpenOnuAc.GetDeviceHandler(oo.deviceID); !exist {
		logger.Debugw(ctx, "delete_device in progress - skip write request", log.Fields{"device-id": oo.deviceID})
		oo.chOnuKvProcessingStep <- aProcessingStep
		oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
		return
	}
	oo.baseDeviceHandler.RLockMutexDeletionInProgressFlag()
	if oo.baseDeviceHandler.GetDeletionInProgress() {
		logger.Debugw(ctx, "delete_device in progress - skip write request", log.Fields{"device-id": oo.deviceID})
		oo.chOnuKvProcessingStep <- aProcessingStep
		oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
		oo.baseDeviceHandler.RUnlockMutexDeletionInProgressFlag()
		return
	}
	oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
	oo.baseDeviceHandler.RUnlockMutexDeletionInProgressFlag()

	oo.mutexOnuKVStore.Lock()
	err = oo.onuKVStore.Put(ctx, oo.onuKVStorePath, Value)
	oo.mutexOnuKVStore.Unlock()
	if err != nil {
		logger.Errorw(ctx, "unable to write ONU-data into KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
		oo.chOnuKvProcessingStep <- 0 //error indication
		return
	}
	oo.chOnuKvProcessingStep <- aProcessingStep //done
}

// UpdateOnuUniTpPath - TODO: add comment
func (oo *OnuDeviceEntry) UpdateOnuUniTpPath(ctx context.Context, aUniID uint8, aTpID uint8, aPathString string) bool {
	/* within some specific InterAdapter processing request write/read access to data is ensured to be sequentially,
	   as also the complete sequence is ensured to 'run to completion' before some new request is accepted
	   no specific concurrency protection to SOnuPersistentData is required here
	*/
	oo.MutexPersOnuConfig.Lock()
	defer oo.MutexPersOnuConfig.Unlock()

	for k, v := range oo.SOnuPersistentData.PersUniConfig {
		if v.PersUniID == aUniID {
			existingPath, ok := oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID]
			logger.Debugw(ctx, "PersUniConfig-entry exists", log.Fields{"device-id": oo.deviceID, "uniID": aUniID,
				"tpID": aTpID, "path": aPathString, "existingPath": existingPath, "ok": ok})
			if !ok {
				logger.Debugw(ctx, "tp-does-not-exist", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "tpID": aTpID, "path": aPathString})
			}
			if existingPath != aPathString {
				if aPathString == "" {
					//existing entry to be deleted
					logger.Debugw(ctx, "UniTp delete path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
					oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = ""
				} else {
					//existing entry to be modified
					logger.Debugw(ctx, "UniTp modify path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
					oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = aPathString
				}
				return true
			}
			//entry already exists
			if aPathString == "" {
				//no active TechProfile
				logger.Debugw(ctx, "UniTp path has already been removed - no AniSide config to be removed", log.Fields{
					"device-id": oo.deviceID, "uniID": aUniID})
			} else {
				//the given TechProfile already exists and is assumed to be active - update devReason as if the config has been done here
				//was needed e.g. in voltha POD Tests:Validate authentication on a disabled ONU
				//  (as here the TechProfile has not been removed with the disable-device before the new enable-device)
				logger.Debugw(ctx, "UniTp path already exists - TechProfile supposed to be active", log.Fields{
					"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
				//no deviceReason update (DeviceProcStatusUpdate) here to ensure 'omci_flows_pushed' state within disable/enable procedure of ATT scenario
				//  (during which the flows are removed/re-assigned but the techProf is left active)
				//and as the TechProfile is regarded as active we have to verify, if some flow configuration still waits on it
				//  (should not be the case, but should not harm or be more robust ...)
				// and to be sure, that for some reason the corresponding TpDelete was lost somewhere in history
				//  we also reset a possibly outstanding delete request - repeated TpConfig is regarded as valid for waiting flow config
				if oo.pOnuTP != nil {
					oo.pOnuTP.SetProfileToDelete(aUniID, aTpID, false)
				}
				go oo.baseDeviceHandler.VerifyVlanConfigRequest(ctx, aUniID, aTpID)
			}
			return false //indicate 'no change' - nothing more to do, TechProf inter-adapter message is return with success anyway here
		}
	}
	//no entry exists for uniId

	if aPathString == "" {
		//delete request in non-existing state , accept as no change
		logger.Debugw(ctx, "UniTp path already removed", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
		return false
	}
	//new entry to be created
	logger.Debugw(ctx, "New UniTp path set", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
	perSubTpPathMap := make(map[uint8]string)
	perSubTpPathMap[aTpID] = aPathString
	oo.SOnuPersistentData.PersUniConfig =
		append(oo.SOnuPersistentData.PersUniConfig, uniPersConfig{PersUniID: aUniID, PersTpPathMap: perSubTpPathMap, PersFlowParams: make([]cmn.UniVlanFlowParams, 0)})
	return true
}

// UpdateOnuUniFlowConfig - TODO: add comment
func (oo *OnuDeviceEntry) UpdateOnuUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]cmn.UniVlanFlowParams) {

	oo.MutexPersOnuConfig.Lock()
	defer oo.MutexPersOnuConfig.Unlock()

	for k, v := range oo.SOnuPersistentData.PersUniConfig {
		if v.PersUniID == aUniID {
			oo.SOnuPersistentData.PersUniConfig[k].PersFlowParams = make([]cmn.UniVlanFlowParams, len(*aUniVlanFlowParams))
			copy(oo.SOnuPersistentData.PersUniConfig[k].PersFlowParams, *aUniVlanFlowParams)
			return
		}
	}
	//flow update was faster than tp-config - create PersUniConfig-entry
	//TODO!!: following activity to 'add' some new uni entry might not be quite correct if this function is called to clear the data
	//  (e.g after flow removal from RemoveUniFlowParams()).
	//  This has the effect of misleading indication that there is still some active UNI entry, even though there might be only some nil flow entry
	//  The effect of this flaw is that at TechProfile removal there is an additional attempt to remove the entry even though no techProfile exists anymore
	//  The code is not changed here because of the current release lane, changes might have unexpected secondary effects, perhaps later with more elaborate tests
	tmpConfig := uniPersConfig{PersUniID: aUniID, PersTpPathMap: make(map[uint8]string), PersFlowParams: make([]cmn.UniVlanFlowParams, len(*aUniVlanFlowParams))}
	copy(tmpConfig.PersFlowParams, *aUniVlanFlowParams)
	oo.SOnuPersistentData.PersUniConfig = append(oo.SOnuPersistentData.PersUniConfig, tmpConfig)
}

func (oo *OnuDeviceEntry) waitForTimeoutOrCompletion(
	ctx context.Context, aChOnuProcessingStep <-chan uint8, aProcessingStep uint8) bool {
	select {
	case <-ctx.Done():
		logger.Warnw(ctx, "processing not completed in-time!",
			log.Fields{"device-id": oo.deviceID, "error": ctx.Err()})
		return false
	case rxStep := <-aChOnuProcessingStep:
		if rxStep == aProcessingStep {
			return true
		}
		//all other values are not accepted - including 0 for error indication
		logger.Warnw(ctx, "Invalid processing step received: abort!",
			log.Fields{"device-id": oo.deviceID,
				"wantedStep": aProcessingStep, "haveStep": rxStep})
		return false
	}
}

// ResetKvProcessingErrorIndication - TODO: add comment
func (oo *OnuDeviceEntry) ResetKvProcessingErrorIndication() {
	oo.mutexOnuKVStoreProcResult.Lock()
	oo.onuKVStoreProcResult = nil
	oo.mutexOnuKVStoreProcResult.Unlock()
}

// GetKvProcessingErrorIndication - TODO: add comment
func (oo *OnuDeviceEntry) GetKvProcessingErrorIndication() error {
	oo.mutexOnuKVStoreProcResult.RLock()
	value := oo.onuKVStoreProcResult
	oo.mutexOnuKVStoreProcResult.RUnlock()
	return value
}

func (oo *OnuDeviceEntry) setKvProcessingErrorIndication(value error) {
	oo.mutexOnuKVStoreProcResult.Lock()
	oo.onuKVStoreProcResult = value
	oo.mutexOnuKVStoreProcResult.Unlock()
}

// IncrementMibDataSync - TODO: add comment
func (oo *OnuDeviceEntry) IncrementMibDataSync(ctx context.Context) {
	oo.MutexPersOnuConfig.Lock()
	defer oo.MutexPersOnuConfig.Unlock()
	if oo.SOnuPersistentData.PersMibDataSyncAdpt < 255 {
		oo.SOnuPersistentData.PersMibDataSyncAdpt++
	} else {
		// per G.984 and G.988 overflow starts over at 1 given 0 is reserved for reset
		oo.SOnuPersistentData.PersMibDataSyncAdpt = 1
	}
	logger.Debugf(ctx, "mibDataSync updated - mds: %d - device-id: %s", oo.SOnuPersistentData.PersMibDataSyncAdpt, oo.deviceID)
}

// ModifySwImageInactiveVersion - updates the inactive SW image version stored
func (oo *OnuDeviceEntry) ModifySwImageInactiveVersion(ctx context.Context, aImageVersion string) {
	oo.mutexOnuSwImageIndications.Lock()
	defer oo.mutexOnuSwImageIndications.Unlock()
	logger.Debugw(ctx, "software-image set inactive version", log.Fields{
		"device-id": oo.deviceID, "version": aImageVersion})
	oo.onuSwImageIndications.InActiveEntityEntry.Version = aImageVersion
	//inactive SW version is not part of persistency data (yet) - no need to update that
}

// ModifySwImageActiveCommit - updates the active SW commit flag stored
func (oo *OnuDeviceEntry) ModifySwImageActiveCommit(ctx context.Context, aCommitted uint8) {
	oo.mutexOnuSwImageIndications.Lock()
	defer oo.mutexOnuSwImageIndications.Unlock()
	logger.Debugw(ctx, "software-image set active entity commit flag", log.Fields{
		"device-id": oo.deviceID, "committed": aCommitted})
	oo.onuSwImageIndications.ActiveEntityEntry.IsCommitted = aCommitted
	//commit flag is not part of persistency data (yet) - no need to update that
}

// GetActiveImageVersion - returns the active SW image version stored
func (oo *OnuDeviceEntry) GetActiveImageVersion(ctx context.Context) string {
	oo.mutexOnuSwImageIndications.RLock()
	if oo.onuSwImageIndications.ActiveEntityEntry.Valid {
		value := oo.onuSwImageIndications.ActiveEntityEntry.Version
		oo.mutexOnuSwImageIndications.RUnlock()
		return value
	}
	oo.mutexOnuSwImageIndications.RUnlock()
	logger.Debugw(ctx, "Active Image is not valid", log.Fields{"device-id": oo.deviceID})
	return ""
}

// GetInactiveImageVersion - TODO: add comment
func (oo *OnuDeviceEntry) GetInactiveImageVersion(ctx context.Context) string {
	oo.mutexOnuSwImageIndications.RLock()
	if oo.onuSwImageIndications.InActiveEntityEntry.Valid {
		value := oo.onuSwImageIndications.InActiveEntityEntry.Version
		oo.mutexOnuSwImageIndications.RUnlock()
		return value
	}
	oo.mutexOnuSwImageIndications.RUnlock()
	logger.Debugw(ctx, "Inactive Image is not valid", log.Fields{"device-id": oo.deviceID})
	return ""
}

func (oo *OnuDeviceEntry) buildMibTemplatePath() string {
	oo.MutexPersOnuConfig.RLock()
	defer oo.MutexPersOnuConfig.RUnlock()
	return fmt.Sprintf(cSuffixMibTemplateKvStore, oo.SOnuPersistentData.PersVendorID, oo.SOnuPersistentData.PersEquipmentID, oo.SOnuPersistentData.PersActiveSwVersion)
}

// AllocateFreeTcont - TODO: add comment
func (oo *OnuDeviceEntry) AllocateFreeTcont(ctx context.Context, allocID uint16) (uint16, bool, error) {
	logger.Debugw(ctx, "allocate-free-tcont", log.Fields{"device-id": oo.deviceID, "allocID": allocID,
		"allocated-instances": oo.SOnuPersistentData.PersTcontMap})

	oo.mutexTcontMap.Lock()
	defer oo.mutexTcontMap.Unlock()
	if entityID, ok := oo.SOnuPersistentData.PersTcontMap[allocID]; ok {
		//tcont already allocated before, return the used instance-id
		return entityID, true, nil
	}
	//First allocation of tcont. Find a free instance
	if tcontInstKeys := oo.pOnuDB.GetSortedInstKeys(ctx, me.TContClassID); len(tcontInstKeys) > 0 {
		logger.Debugw(ctx, "allocate-free-tcont-db-keys", log.Fields{"device-id": oo.deviceID, "keys": tcontInstKeys})
		for _, instID := range tcontInstKeys {
			instExist := false
			//If this instance exist in map, it means it is not  empty. It is allocated before
			for _, v := range oo.SOnuPersistentData.PersTcontMap {
				if v == instID {
					instExist = true
					break
				}
			}
			if !instExist {
				oo.SOnuPersistentData.PersTcontMap[allocID] = instID
				return instID, false, nil
			}
		}
	}
	return 0, false, fmt.Errorf(fmt.Sprintf("no-free-tcont-left-for-device-%s", oo.deviceID))

}

// FreeTcont - TODO: add comment
func (oo *OnuDeviceEntry) FreeTcont(ctx context.Context, allocID uint16) {
	logger.Debugw(ctx, "free-tcont", log.Fields{"device-id": oo.deviceID, "alloc": allocID})
	oo.mutexTcontMap.Lock()
	defer oo.mutexTcontMap.Unlock()
	delete(oo.SOnuPersistentData.PersTcontMap, allocID)
}

// GetDevOmciCC - TODO: add comment
func (oo *OnuDeviceEntry) GetDevOmciCC() *cmn.OmciCC {
	return oo.PDevOmciCC
}

// GetOnuDB - TODO: add comment
func (oo *OnuDeviceEntry) GetOnuDB() *devdb.OnuDeviceDB {
	return oo.pOnuDB
}

// GetPersSerialNumber - TODO: add comment
func (oo *OnuDeviceEntry) GetPersSerialNumber() string {
	value := oo.SOnuPersistentData.PersSerialNumber
	return value
}

// GetPersVendorID - TODO: add comment
func (oo *OnuDeviceEntry) GetPersVendorID() string {
	value := oo.SOnuPersistentData.PersVendorID
	return value
}

// GetPersEquipmentID - TODO: add comment
func (oo *OnuDeviceEntry) GetPersEquipmentID() string {
	value := oo.SOnuPersistentData.PersEquipmentID
	return value
}

// GetMibUploadFsmCommChan - TODO: add comment
func (oo *OnuDeviceEntry) GetMibUploadFsmCommChan() chan cmn.Message {
	return oo.PMibUploadFsm.CommChan
}

// GetMibDownloadFsmCommChan - TODO: add comment
func (oo *OnuDeviceEntry) GetMibDownloadFsmCommChan() chan cmn.Message {
	return oo.PMibDownloadFsm.CommChan
}

// GetOmciRebootMsgRevChan - TODO: add comment
func (oo *OnuDeviceEntry) GetOmciRebootMsgRevChan() chan cmn.Message {
	return oo.omciRebootMessageReceivedChannel
}

// LockMutexOnuSwImageIndications - TODO: add comment
func (oo *OnuDeviceEntry) LockMutexOnuSwImageIndications() {
	oo.mutexOnuSwImageIndications.Lock()
}

// UnlockMutexOnuSwImageIndications - TODO: add comment
func (oo *OnuDeviceEntry) UnlockMutexOnuSwImageIndications() {
	oo.mutexOnuSwImageIndications.Unlock()
}

// GetOnuSwImageIndications - TODO: add comment
func (oo *OnuDeviceEntry) GetOnuSwImageIndications() cmn.SswImageIndications {
	return oo.onuSwImageIndications
}

// SetOnuSwImageIndications - TODO: add comment
func (oo *OnuDeviceEntry) SetOnuSwImageIndications(value cmn.SswImageIndications) {
	oo.onuSwImageIndications = value
}

// LockMutexPersOnuConfig - TODO: add comment
func (oo *OnuDeviceEntry) LockMutexPersOnuConfig() {
	oo.MutexPersOnuConfig.Lock()
}

// UnlockMutexPersOnuConfig - TODO: add comment
func (oo *OnuDeviceEntry) UnlockMutexPersOnuConfig() {
	oo.MutexPersOnuConfig.Unlock()
}

// GetPersActiveSwVersion - TODO: add comment
func (oo *OnuDeviceEntry) GetPersActiveSwVersion() string {
	return oo.SOnuPersistentData.PersActiveSwVersion
}

// SetPersActiveSwVersion - TODO: add comment
func (oo *OnuDeviceEntry) SetPersActiveSwVersion(value string) {
	oo.SOnuPersistentData.PersActiveSwVersion = value
}

// SetReconcilingFlows - TODO: add comment
func (oo *OnuDeviceEntry) SetReconcilingFlows(value bool) {
	oo.mutexReconcilingFlowsFlag.Lock()
	oo.reconcilingFlows = value
	oo.mutexReconcilingFlowsFlag.Unlock()
}

// SetChReconcilingFlowsFinished - TODO: add comment
func (oo *OnuDeviceEntry) SetChReconcilingFlowsFinished(value bool) {
	oo.chReconcilingFlowsFinished <- value
}

// IsReconcilingFlows - TODO: add comment
func (oo *OnuDeviceEntry) IsReconcilingFlows() bool {
	oo.mutexReconcilingFlowsFlag.RLock()
	value := oo.reconcilingFlows
	oo.mutexReconcilingFlowsFlag.RUnlock()
	return value
}
