/*
* 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 (
	"encoding/json"
	"errors"
	"context"
	"sync"

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

// VoltShaperConfig is shaper profile configuration structure
type VoltShaperConfig struct {
	Name      string
	BurstSize uint32
}

// VoltBwConfig is bandwidth profile configuration structure
type VoltBwConfig struct {
	Name string
	Fir  uint32
	Air  uint32
	Eir  uint32
}

// VoltBandwidthProf is bandwidth profile stored at VGC
type VoltBandwidthProf struct {
	VoltBwConfig
}

// VoltShaperProf is shaper profile stored at VGC
type VoltShaperProf struct {
	VoltShaperConfig
}

// VoltMeterProf is meter profile stored at VGC
type VoltMeterProf struct {
	VoltMeter
}

// MeterMgr structure
type MeterMgr struct {
	Meters      sync.Map
	MetersByID  sync.Map
	LastMeterID uint32
}

// Init to initialize MeterMgr
func (m *MeterMgr) Init() {
	m.LastMeterID = 0
}

// VoltMeter : A VOLT meter is a combination of BW and shaper profiles
// The ID is generated by the VOLT application
type VoltMeter struct {
	Name               string
	ID                 uint32
	Fir                uint32
	Air                uint32
	Eir                uint32
	BurstSize          uint32
	AssociatedServices uint32
	Version            string
	Cir                uint32
	Cbs                uint32
	Pir                uint32
	Pbs                uint32
	Gir                uint32
	Ebs                uint32
}

// WriteToDb to write a meter profile to DB
func (vm *VoltMeter) WriteToDb(cntx context.Context) error {
	vm.Version = database.PresentVersionMap[database.MeterPath]
	b, err := json.Marshal(vm)
	if err != nil {
		return err
	}
	if err1 := db.PutMeter(cntx, vm.Name, string(b)); err1 != nil {
		return err1
	}
	return nil
}

// DelFromDb to delete a meter profile from DB
func (vm *VoltMeter) DelFromDb(cntx context.Context) {
	_ = db.DelMeter(cntx, vm.Name)
}

// GetMeterByName to get meter by name
func (m *MeterMgr) GetMeterByName(name string) (*VoltMeter, bool) {
	meter, ok := m.Meters.Load(name)
	logger.Infow(ctx, "Meter Obtained Name", log.Fields{"Meter": meter})
	if ok {
		return meter.(*VoltMeter), ok
	}
	return nil, ok
}

// GetMeterByID to get meter by ID
func (m *MeterMgr) GetMeterByID(id uint32) (*VoltMeter, bool) {
	meter, ok := m.MetersByID.Load(id)
	logger.Infow(ctx, "Meter Obtained ID", log.Fields{"Meter": meter})
	if ok {
		return meter.(*VoltMeter), ok
	}
	return nil, ok
}

// AddMeter to add meter
func (m *MeterMgr) AddMeter(meter *VoltMeter) {
	m.Meters.Store(meter.Name, meter)
	m.MetersByID.Store(meter.ID, meter)
	logger.Infow(ctx, "Meter Added/Updated", log.Fields{"Meter": meter, "Name": meter.Name, "Id": meter.ID})
}

// DelMeter to delete meter
func (m *MeterMgr) DelMeter(meter *VoltMeter) {
	m.Meters.Delete(meter.Name)
	m.MetersByID.Delete(meter.ID)
	logger.Infow(ctx, "Meter Deleted", log.Fields{"Meter": meter, "Name": meter.Name, "Id": meter.ID})
}

// AddToDevice to add meter to the device
func (vm *VoltMeter) AddToDevice(port string, device string, aggVM *VoltMeter) {
	logger.Debugw(ctx, "Adding Meter To Device", log.Fields{"Id": vm.ID, "Device": device, "Port": port})
	meter := of.NewMeter(vm.ID)
	// meter.AddBand(vm.Air, vm.BurstSize)
	// meter.AddBand(vm.Eir, vm.BurstSize)
	// if aggVM != nil {
	// 	meter.AddBand(aggVM.Air, aggVM.BurstSize)
	// 	meter.AddBand(aggVM.Eir, aggVM.BurstSize)
	// }

	//Community VGC Impl

	//Set Cir
	if vm.Cir != 0 {
		meter.AddBand(vm.Cir, vm.Cbs)
	}

	//Set Air to 0 if both air & gir are set
	if vm.Air != 0 && vm.Gir != 0 {
		vm.Air = 0
	}

	//Set Pir & Pbs
	var pir uint32
	var pbs uint32
	if vm.Pir != 0 {
		pir = vm.Pir
	} else {
		pir = vm.Eir + vm.Cir + vm.Gir + vm.Air
	}

	if vm.Pbs != 0 {
		pbs = vm.Pbs
	} else {
		pbs = vm.Ebs + vm.Cbs
	}
	meter.AddBand(pir, pbs)

	//Set Gir
	if vm.Gir != 0 {
		meter.AddBand(vm.Gir, 0)
	}

	logger.Infow(ctx, "Meter Config", log.Fields{"Cir": vm.Cir, "Air": vm.Air, "Pir": vm.Pir, "Gir": vm.Gir, "Eir": vm.Eir})
	logger.Infow(ctx, "Meter Burst Config", log.Fields{"Cbs": vm.Cbs, "Pbs": vm.Pbs})
	logger.Infow(ctx, "Meter Burst Oper", log.Fields{"Pir": pir, "Pbs": pbs})
	//Set Air
	// Air is used in place of Gir only if Gir is
	// not present and Air is not 0
	if vm.Air != 0 {
		meter.AddBand(vm.Air, 0)
	}

	logger.Debugw(ctx, "Total Bands are", log.Fields{"meter": *meter})
	if err := cntlr.GetController().ModMeter(port, device, of.MeterCommandAdd, meter); err != nil {
		logger.Warnw(ctx, "Add meter to device Failed", log.Fields{"Id": vm.ID, "meter": *meter, "Error": err})
	}
}

// AddMeterToDevice to add meter to the device
func (m *MeterMgr) AddMeterToDevice(port string, device string, meterID uint32, aggMeterID uint32) {
	var aggVM *VoltMeter
	vm, err := m.GetMeterByProfID(meterID)
	if err == nil {
		if 0 != aggMeterID { //Assuming valid meter id will never be 0
			if aggVM, err = m.GetMeterByProfID(aggMeterID); err != nil {
				logger.Warnw(ctx, "Aggregated Meter not found", log.Fields{"Id": aggMeterID})
			}
		}
		vm.AddToDevice(port, device, aggVM)
	} else {
		logger.Warnw(ctx, "Meter not found", log.Fields{"Id": meterID})
	}
}

// RestoreMetersFromDb to read from the DB and restore all the services
func (m *MeterMgr) RestoreMetersFromDb(cntx context.Context) {
	// VNETS must be learnt first
	logger.Infow(ctx, "LastMeterID on restart", log.Fields{"LastMeterID": m.LastMeterID})
	ms, _ := db.GetMeters(cntx)
	for _, mt := range ms {
		b, ok := mt.Value.([]byte)
		if !ok {
			logger.Warn(ctx, "The value type is not []byte")
			continue
		}
		var meter VoltMeter
		err := json.Unmarshal(b, &meter)
		if err != nil {
			logger.Warn(ctx, "Unmarshal of meter profile failed")
			continue
		}
		logger.Infow(ctx, "Retrieved Meter", log.Fields{"Meter": meter.Name})
		m.AddMeter(&meter)
		if meter.ID > m.LastMeterID {
			m.LastMeterID = meter.ID
		}
	}
	logger.Infow(ctx, "LastMeterID on reading DB", log.Fields{"LastMeterID": m.LastMeterID})
}

// AddMeterProf to add the meter profile name as key
func (va *VoltApplication) AddMeterProf(cntx context.Context, cfg VoltMeter) {

	mm := &va.MeterMgr
	if _, ok := mm.GetMeterByName(cfg.Name); ok {
		logger.Warnw(ctx, "Meter profile exists", log.Fields{"Name": cfg.Name})
		return
	}

	mm.LastMeterID++
	//FIX-ME: Hardcoded the meter-id temp till meter delete is introduced
	//Restriction: Only one meter profile should be used across all services
	//	id := uint32(1) //mm.LastMeterId
	id := mm.LastMeterID
	cfg.ID = id
	mm.AddMeter(&cfg)
	if err := cfg.WriteToDb(cntx); err != nil {
		logger.Warnw(ctx, "MeterProf Write to DB Failed", log.Fields{"MeterConfig": cfg, "Error": err})
	}
}

// UpdateMeterProf to update the meter profile
func (va *VoltApplication) UpdateMeterProf(cntx context.Context, cfg VoltMeter) {
	mm := &va.MeterMgr
	if _, ok := mm.GetMeterByName(cfg.Name); !ok {
		logger.Warnw(ctx, "Meter profile does not exist", log.Fields{"Name": cfg.Name})
		return
	}
	mm.AddMeter(&cfg)
	if err := cfg.WriteToDb(cntx); err != nil {
		logger.Warnw(ctx, "MeterProf Write to DB Failed", log.Fields{"MeterConfig": cfg, "Error": err})
	}
}

// GetMeterByProfID to get a meter based on the identities of bandwidth profile and shaper
// profile names.
func (m *MeterMgr) GetMeterByProfID(id uint32) (*VoltMeter, error) {
	if mtr, ok := m.GetMeterByID(id); ok {
		return mtr, nil
	}
	return nil, errors.New("Meter Missing")
}

// GetMeter to get a meter based on the identities of bandwidth profile and shaper
// profile names.
func (m *MeterMgr) GetMeter(meterID string) (*VoltMeter, error) {
	if mt, ok := m.GetMeterByName(meterID); ok {
		return mt, nil
	}
	return nil, errors.New("Meter Missing")
}

// DeleteFromDevice to delete meter from the device
func (vm *VoltMeter) DeleteFromDevice(port string, device string) {

	meter := of.NewMeter(vm.ID)

	logger.Debugw(ctx, "Delete meter from device", log.Fields{"Id": vm.ID, "meter": *meter})
	if err := cntlr.GetController().ModMeter(port, device, of.MeterCommandDel, meter); err != nil {
		logger.Warnw(ctx, "Delete meter from device Failed", log.Fields{"Id": vm.ID, "meter": *meter, "Error": err})
	}
}

// DelMeterProf to delete meter profile
func (va *VoltApplication) DelMeterProf(cntx context.Context, name string) error {
	mm := &va.MeterMgr
	if _, ok := mm.GetMeterByName(name); !ok {
		logger.Warnw(ctx, "Meter profile does not exist", log.Fields{"Name": name})
		return errors.New("Meter profile doesn't exist")
	}
	cfg, _ := mm.GetMeterByName(name)
	if cfg.AssociatedServices != 0 {
		logger.Warnw(ctx, "Mismatch in submgr and vgc oeter profile service reference",
			log.Fields{"MeterProfile": name, "serviceCount": cfg.AssociatedServices})
		return errors.New("Service reference is not 0")
	}
	//TODO : delete from all devices
	delmeterFromDevice := func(key interface{}, value interface{}) bool {
		device := key.(string)
		port, _ := GetApplication().GetNniPort(device)
		cfg.DeleteFromDevice(port, device)
		return true
	}
	va.DevicesDisc.Range(delmeterFromDevice)
	cfg.DelFromDb(cntx)
	//Delete meter from device will be invoked by caller separately
	mm.DelMeter(cfg)
	return nil
}
