/*
* 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"
	"github.com/opencord/voltha-lib-go/v7/pkg/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.Debug(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
}
