/*
 * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
package adaptercoreonu

import (
	"context"
	//"errors"
	//"sync"
	//"time"

	"github.com/looplab/fsm"
	"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"

	//"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
	"github.com/opencord/voltha-lib-go/v3/pkg/log"
	//ic "github.com/opencord/voltha-protos/v3/go/inter_container"
	//"github.com/opencord/voltha-protos/v3/go/openflow_13"
	//"github.com/opencord/voltha-protos/v3/go/voltha"
)

type OnuDeviceEvent int

const (
	// Events of interest to Device Adapters and OpenOMCI State Machines
	DeviceStatusInit     OnuDeviceEvent = 0 // OnuDeviceEntry default start state
	MibDatabaseSync      OnuDeviceEvent = 1 // MIB database sync (upload done)
	OmciCapabilitiesDone OnuDeviceEvent = 2 // OMCI ME and message type capabilities known
	MibDownloadDone      OnuDeviceEvent = 3 // MIB database sync (upload done)
	PortLinkUp           OnuDeviceEvent = 4 // Port link state change
	PortLinkDw           OnuDeviceEvent = 5 // Port link state change
	// Add other events here as needed (alarms separate???)
)

type activityDescr struct {
	databaseClass   func() error
	advertiseEvents bool
	auditDelay      uint16
	//tasks           map[string]func() error
}
type OmciDeviceFsms map[string]activityDescr

//OntDeviceEntry structure holds information about the attached FSM'as and their communication
type OnuDeviceEntry struct {
	deviceID          string
	baseDeviceHandler *DeviceHandler
	coreProxy         adapterif.CoreProxy
	adapterProxy      adapterif.AdapterProxy
	started           bool
	PDevOmciCC        *OmciCC
	//lockDeviceEntries           sync.RWMutex
	mibDbClass    func() error
	supportedFsms OmciDeviceFsms
	MibSyncFsm    *fsm.FSM
	MibSyncChan   chan Message
	devState      OnuDeviceEvent
	mibAuditDelay uint16
}

//OnuDeviceEntry 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,
	device_id string, device_Handler *DeviceHandler,
	core_proxy adapterif.CoreProxy, adapter_proxy adapterif.AdapterProxy,
	supported_Fsms_Ptr *OmciDeviceFsms) *OnuDeviceEntry {
	logger.Infow("init-onuDeviceEntry", log.Fields{"deviceId": device_id})
	var onuDeviceEntry OnuDeviceEntry
	onuDeviceEntry.started = false
	onuDeviceEntry.deviceID = device_id
	onuDeviceEntry.baseDeviceHandler = device_Handler
	onuDeviceEntry.coreProxy = core_proxy
	onuDeviceEntry.adapterProxy = adapter_proxy
	onuDeviceEntry.devState = DeviceStatusInit
	//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
	if supported_Fsms_Ptr != nil {
		onuDeviceEntry.supportedFsms = *supported_Fsms_Ptr
	} else {
		//var mibSyncFsm = NewMibSynchronizer()
		// use some internaö defaults, if not defined from outside
		onuDeviceEntry.supportedFsms = OmciDeviceFsms{
			"mib-synchronizer": {
				//mibSyncFsm,        // Implements the MIB synchronization state machine
				onuDeviceEntry.MibDbVolatileDict, // Implements volatile ME MIB database
				true,                             // Advertise events on OpenOMCI event bus
				60,                               // 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("access2mibDbClass")
	go onuDeviceEntry.mibDbClass()
	onuDeviceEntry.mibAuditDelay = onuDeviceEntry.supportedFsms["mib-synchronizer"].auditDelay
	logger.Debugw("MibAudit is set to", log.Fields{"Delay": onuDeviceEntry.mibAuditDelay})

	// Omci related Mib sync state machine
	onuDeviceEntry.MibSyncFsm = fsm.NewFSM(
		"disabled",
		fsm.Events{

			{Name: "start", Src: []string{"disabled"}, Dst: "starting"},

			{Name: "load_mib_template", Src: []string{"starting"}, Dst: "loading_mib_template"},
			{Name: "upload_mib", Src: []string{"loading_mib_template"}, Dst: "uploading"},
			{Name: "examine_mds", Src: []string{"starting"}, Dst: "examining_mds"},

			{Name: "success", Src: []string{"loading_mib_template"}, Dst: "in_sync"},
			{Name: "success", Src: []string{"uploading"}, Dst: "in_sync"},

			{Name: "success", Src: []string{"examining_mds"}, Dst: "in_sync"},
			{Name: "mismatch", Src: []string{"examining_mds"}, Dst: "resynchronizing"},

			{Name: "audit_mib", Src: []string{"in_sync"}, Dst: "auditing"},

			{Name: "success", Src: []string{"out_of_sync"}, Dst: "in_sync"},
			{Name: "audit_mib", Src: []string{"out_of_sync"}, Dst: "auditing"},

			{Name: "success", Src: []string{"auditing"}, Dst: "in_sync"},
			{Name: "mismatch", Src: []string{"auditing"}, Dst: "resynchronizing"},
			{Name: "force_resync", Src: []string{"auditing"}, Dst: "resynchronizing"},

			{Name: "success", Src: []string{"resynchronizing"}, Dst: "in_sync"},
			{Name: "diffs_found", Src: []string{"resynchronizing"}, Dst: "out_of_sync"},

			{Name: "timeout", Src: []string{"loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "starting"},

			{Name: "stop", Src: []string{"starting", "loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "disabled"},
		},

		fsm.Callbacks{
			"enter_state":                func(e *fsm.Event) { onuDeviceEntry.logStateChange(e) },
			"enter_starting":             func(e *fsm.Event) { onuDeviceEntry.enterStartingState(e) },
			"enter_loading_mib_template": func(e *fsm.Event) { onuDeviceEntry.enterLoadingMibTemplateState(e) },
			"enter_uploading":            func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(e) },
			"enter_examining_mds":        func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(e) },
			"enter_resynchronizing":      func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(e) },
			"enter_auditing":             func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(e) },
			"enter_out_of_sync":          func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(e) },
			"enter_in_sync":              func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(e) },
		},
	)

	// 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.Info("starting-OnuDeviceEntry")

	oo.PDevOmciCC = NewOmciCC(ctx, oo, oo.deviceID, oo.baseDeviceHandler,
		oo.coreProxy, oo.adapterProxy)

	//TODO .....
	//mib_db.start()
	oo.started = true
	logger.Info("OnuDeviceEntry-started, but not yet mib_db!!!")
	return nil
}

//Stop terminates the session
func (oo *OnuDeviceEntry) Stop(ctx context.Context) error {
	logger.Info("stopping-OnuDeviceEntry")
	oo.started = false
	//oo.exitChannel <- 1
	logger.Info("OnuDeviceEntry-stopped")
	return nil
}

//Relay the InSync message via Handler to Rw core - Status update
func (oo *OnuDeviceEntry) transferSystemEvent(dev_Event OnuDeviceEvent) error {
	logger.Debugw("relaying system-event", log.Fields{"Event": dev_Event})
	// 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 dev_Event == MibDatabaseSync {
		if oo.devState < MibDatabaseSync { //devState has not been synced yet
			oo.devState = MibDatabaseSync
			go oo.baseDeviceHandler.DeviceStateUpdate(dev_Event)
			//TODO!!! device control: next step: start MIB capability verification from here ?!!!
		} else {
			logger.Debugw("mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
		}
	} else if dev_Event == MibDownloadDone {
		if oo.devState < MibDownloadDone { //devState has not been synced yet
			oo.devState = MibDownloadDone
			go oo.baseDeviceHandler.DeviceStateUpdate(dev_Event)
		} else {
			logger.Debugw("mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
		}
	} else {
		logger.Warnw("device-event not yet handled", log.Fields{"state": dev_Event})
	}
	return nil
}
