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

import (
	"context"
	"time"

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

// ModMeterTask structure
type ModMeterTask struct {
	ctx       context.Context
	meter     *of.Meter
	device    *Device
	timestamp string
	command   of.MeterCommand
	taskID    uint8
}

// NewModMeterTask is the constructor for ModMeterTask
func NewModMeterTask(ctx context.Context, command of.MeterCommand, meter *of.Meter, device *Device) *ModMeterTask {
	var mmt ModMeterTask
	mmt.device = device
	mmt.meter = meter
	mmt.ctx = ctx
	mmt.command = command
	tstamp := (time.Now()).Format(time.RFC3339Nano)
	mmt.timestamp = tstamp
	return &mmt
}

// Name returns name of the task
func (mmt *ModMeterTask) Name() string {
	return "Add Flows Task"
}

// TaskID returns task Id of the task
func (mmt *ModMeterTask) TaskID() uint8 {
	return mmt.taskID
}

// Timestamp returns time stamp for the task
func (mmt *ModMeterTask) Timestamp() string {
	return mmt.timestamp
}

// Stop to stop the task
func (mmt *ModMeterTask) Stop() {
}

// Start to start the task
func (mmt *ModMeterTask) Start(ctx context.Context, taskID uint8) error {
	mmt.taskID = taskID
	mmt.ctx = ctx

	// Temp commenting Sync response handling
	//triggerMeterNotification := func(err error) {

	// 	statusCode, statusMsg := infraerror.GetErrorInfo(err)

	// 	if mmt.command == of.MeterCommandAdd && infraerrorcode.ErrorCode(statusCode) != infraerrorcode.ErrOk {
	// 		mmt.meter.State = of.MeterOperFailure
	// 		mmt.meter.ErrorReason = statusMsg

	// 		logger.Errorw(ctx, "Update Meter Table Failed",
	// 			log.Fields{"meterId": mmt.meter.ID, "meterOp": mmt.command, "Status": statusCode, "errorReason": statusMsg})
	// 		go mmt.device.AddMeterToDb(mmt.meter)
	// 	} else {
	// 		logger.Infow("Meter Mod Result", log.Fields{"meterID": mmt.meter.ID, "Error Code": statusCode})
	// 	}
	// }

	// First add/delete the flows first locally before passing them to actual device
	if mmt.command == of.MeterCommandAdd {
		mmt.meter.State = of.MeterOperPending
		if err := mmt.device.AddMeter(ctx, mmt.meter); err != nil {
			// Meter already exists so we dont have to do anything here
			return nil
		}
		logger.Debugw(ctx, "Updated meter state to pending", log.Fields{"Meter": mmt.meter.ID})
	} else {
		if !mmt.device.DelMeter(ctx, mmt.meter) {
			// Meter doesn't exist so we dont have to do anything here
			return nil
		}
	}

	if mmt.device.State != DeviceStateUP {
		logger.Errorw(ctx, "Update Meter Table Failed: Device State DOWN", log.Fields{"Reason": "Device State DOWN", "Meter": mmt.meter.ID})
		return nil
	}
	meterMod, err := of.MeterUpdate(mmt.device.ID, mmt.command, mmt.meter)
	if err != nil {
		logger.Errorw(ctx, "Update Meter Table Failed", log.Fields{"Reason": err.Error()})
		return err
	}

	if vc := mmt.device.VolthaClient(); vc != nil {
		if _, err = vc.UpdateLogicalDeviceMeterTable(mmt.ctx, meterMod); err != nil {
			logger.Errorw(ctx, "Update Meter Table Failed", log.Fields{"Reason": err.Error()})
		} else {
			mmt.meter.State = of.MeterOperSuccess
			if err = mmt.device.UpdateMeter(ctx, mmt.meter); err != nil {
				// Meter does not exist, update failed
				logger.Error(ctx, "Update meter to DB failed")
			}
			logger.Debugw(ctx, "Updated meter state to success", log.Fields{"Meter": mmt.meter.ID})
		}
		//triggerMeterNotification(err)
		return err
	}

	logger.Error(ctx, "Update Meter Table Failed: Voltha Client Unavailable")
	return nil
}
