/*
* Copyright 2022-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 application

import (
	infraerrorcode "voltha-go-controller/internal/pkg/errorcodes/service"

	"voltha-go-controller/internal/pkg/intf"
	"voltha-go-controller/log"
)

//Generic Framework to enabling all flow based event trigger and handling.
//The eventMapper can be updated for dynamic func caller for future events

//FlowEventType - Type of event enumeration
type FlowEventType string

//FlowEventHandler - Func prototype for flow event handling funcs
type FlowEventHandler func(*FlowEvent, intf.FlowStatus)

var eventMapper map[FlowEventType]FlowEventHandler

const (
	//EventTypeUsIgmpFlowAdded - Event type for IGMP US flow add
	EventTypeUsIgmpFlowAdded FlowEventType = "USIgmpFlowAdded"
	//EventTypeServiceFlowAdded - Event type for Service flow add
	EventTypeServiceFlowAdded FlowEventType = "ServiceFlowAdded"
	//EventTypeControlFlowAdded - Event type for Control flow add
	EventTypeControlFlowAdded FlowEventType = "ControlFlowAdded"

	//EventTypeDeviceFlowRemoved - Event type for Device flow del
	EventTypeDeviceFlowRemoved FlowEventType = "DeviceFlowRemoved"
	//EventTypeMcastFlowRemoved - Event type for Mcast flow del
	EventTypeMcastFlowRemoved FlowEventType = "McastFlowRemoved"

	//EventTypeServiceFlowRemoved - Event type for Service flow del
	EventTypeServiceFlowRemoved FlowEventType = "ServiceFlowRemoved"
	//EventTypeControlFlowRemoved - Event type for Control flow del
	EventTypeControlFlowRemoved FlowEventType = "ControlFlowRemoved"
)

//FlowEvent - Event info for Flow event processing
type FlowEvent struct {
	eType     FlowEventType
	device    string
	cookie    string
	eventData interface{}
}

//InitEventFuncMapper - Initialization of flow event mapper
func InitEventFuncMapper() {
	eventMapper = map[FlowEventType]FlowEventHandler{
		EventTypeUsIgmpFlowAdded:    ProcessUsIgmpFlowAddEvent,
		EventTypeControlFlowAdded:   ProcessControlFlowAddEvent,
		EventTypeServiceFlowAdded:   ProcessServiceFlowAddEvent,
		EventTypeControlFlowRemoved: ProcessControlFlowDelEvent,
		EventTypeServiceFlowRemoved: ProcessServiceFlowDelEvent,
		EventTypeDeviceFlowRemoved:  ProcessDeviceFlowDelEvent,
		EventTypeMcastFlowRemoved:   ProcessMcastFlowDelEvent,
	}
}

//ExecuteFlowEvent - Process flow based event triggers
func ExecuteFlowEvent(vd *VoltDevice, cookie string, flowStatus intf.FlowStatus) bool {
	var event interface{}

	flowEventMap, err := vd.GetFlowEventRegister(flowStatus.FlowModType)
	if err != nil {
		logger.Debugw(ctx, "Flow event map does not exists", log.Fields{"flowMod": flowStatus.FlowModType, "Error": err})
		return false
	}
	flowEventMap.MapLock.Lock()

	if event, _ = flowEventMap.Get(cookie); event == nil {
		logger.Debugw(ctx, "Event already processed or event not registered for the cookie", log.Fields{"Cookie": cookie})
		flowEventMap.MapLock.Unlock()
		return false
	}
	flowEventMap.Remove(cookie)
	flowEventMap.MapLock.Unlock()
	flowEvent := event.(*FlowEvent)
	eventMapper[flowEvent.eType](flowEvent, flowStatus)
	return true
}

//ProcessUsIgmpFlowAddEvent - Process Us Igmp Flow event trigger
func ProcessUsIgmpFlowAddEvent(event *FlowEvent, flowStatus intf.FlowStatus) {

	logger.Infow(ctx, "Processing Post Flow Add Event for US Igmp", log.Fields{"Cookie": event.cookie, "event": event})
	vpv := event.eventData.(*VoltPortVnet)
	if isFlowStatusSuccess(flowStatus.Status, true) {
		vpv.services.Range(ReceiverUpInd)
	} else {
		vpv.IgmpFlowInstallFailure(event.cookie, flowStatus.Status, flowStatus.Reason)
	}
}

//ProcessServiceFlowAddEvent - Process Service Flow event trigger
func ProcessServiceFlowAddEvent(event *FlowEvent, flowStatus intf.FlowStatus) {

	logger.Infow(ctx, "Processing Post Flow Add Event for Service", log.Fields{"Cookie": event.cookie, "event": event})
	vs := event.eventData.(*VoltService)
	if isFlowStatusSuccess(flowStatus.Status, true) {
		vs.FlowInstallSuccess(event.cookie, flowStatus.AdditionalData)
	} else {
		vs.FlowInstallFailure(event.cookie, flowStatus.Status, flowStatus.Reason)
	}
}

//ProcessControlFlowAddEvent - Process Control Flow event trigger
func ProcessControlFlowAddEvent(event *FlowEvent, flowStatus intf.FlowStatus) {

	logger.Infow(ctx, "Processing Post Flow Add Event for VPV", log.Fields{"Cookie": event.cookie, "event": event})
	vpv := event.eventData.(*VoltPortVnet)
	if !isFlowStatusSuccess(flowStatus.Status, true) {
		vpv.FlowInstallFailure(event.cookie, flowStatus.Status, flowStatus.Reason)
	}
}

//ProcessServiceFlowDelEvent - Process Service Flow event trigger
func ProcessServiceFlowDelEvent(event *FlowEvent, flowStatus intf.FlowStatus) {

	logger.Infow(ctx, "Processing Post Flow Remove Event for Service", log.Fields{"Cookie": event.cookie, "event": event})
	vs := event.eventData.(*VoltService)
	if isFlowStatusSuccess(flowStatus.Status, false) {
		vs.FlowRemoveSuccess(event.cookie)
	} else {
		vs.FlowRemoveFailure(event.cookie, flowStatus.Status, flowStatus.Reason)
	}
}

//ProcessControlFlowDelEvent - Process Control Flow event trigger
func ProcessControlFlowDelEvent(event *FlowEvent, flowStatus intf.FlowStatus) {

	logger.Infow(ctx, "Processing Post Flow Remove Event for VPV", log.Fields{"Cookie": event.cookie, "event": event})
	vpv := event.eventData.(*VoltPortVnet)
	if isFlowStatusSuccess(flowStatus.Status, false) {
		vpv.FlowRemoveSuccess(event.cookie, event.device)
	} else {
		vpv.FlowRemoveFailure(event.cookie, event.device, flowStatus.Status, flowStatus.Reason)
	}
}

//ProcessMcastFlowDelEvent - Process Control Flow event trigger
func ProcessMcastFlowDelEvent(event *FlowEvent, flowStatus intf.FlowStatus) {

	logger.Infow(ctx, "Processing Post Flow Remove Event for Mcast/Igmp", log.Fields{"Cookie": event.cookie, "event": event})
	mvp := event.eventData.(*MvlanProfile)
	if isFlowStatusSuccess(flowStatus.Status, false) {
		mvp.FlowRemoveSuccess(event.cookie, event.device)
	} else {
		mvp.FlowRemoveFailure(event.cookie, event.device, flowStatus.Status, flowStatus.Reason)
	}
}

//ProcessDeviceFlowDelEvent - Process Control Flow event trigger
func ProcessDeviceFlowDelEvent(event *FlowEvent, flowStatus intf.FlowStatus) {

	logger.Infow(ctx, "Processing Post Flow Remove Event for VNET", log.Fields{"Cookie": event.cookie, "event": event})
	vnet := event.eventData.(*VoltVnet)
	if isFlowStatusSuccess(flowStatus.Status, false) {
		vnet.FlowRemoveSuccess(event.cookie, event.device)
	} else {
		vnet.FlowRemoveFailure(event.cookie, event.device, flowStatus.Status, flowStatus.Reason)
	}
}

//TODO: Update the func or flowStatus struct once all flow status are based on NB error code
func isFlowStatusSuccess(status uint32, flowAdd bool) bool {
	result := false
	errorCode := infraerrorcode.ErrorCode(status)

	if errorCode == infraerrorcode.ErrOk {
		result = true
	} else if !flowAdd && errorCode == infraerrorcode.ErrNotExists {
		result = true
	}
	return result
}
