/*
* 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"
	"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() error {
	vm.Version = database.PresentVersionMap[database.MeterPath]
	b, err := json.Marshal(vm)
	if err != nil {
		return err
	}
	if err1 := db.PutMeter(vm.Name, string(b)); err1 != nil {
		return err1
	}
	return nil
}

// DelFromDb to delete a meter profile from DB
func (vm *VoltMeter) DelFromDb() {
	_ = db.DelMeter(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() {
	// VNETS must be learnt first
	logger.Infow(ctx, "LastMeterID on restart", log.Fields{"LastMeterID": m.LastMeterID})
	ms, _ := db.GetMeters()
	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(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(); 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(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(); 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(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()
	//Delete meter from device will be invoked by caller separately
	mm.DelMeter(cfg)
	return nil
}
