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

	"voltha-go-controller/database"
	cntlr "voltha-go-controller/internal/pkg/controller"
	"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
	Version            string
	ID                 uint32
	Fir                uint32
	Air                uint32
	Eir                uint32
	BurstSize          uint32
	AssociatedServices uint32
	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{"Name": name, "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, "GetMeter Obtained ID", log.Fields{"ID": id, "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, "Add 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) {
	logger.Debugw(ctx, "Adding Meter To Device", log.Fields{"Agg MeterID": aggMeterID, "Device": device, "Port": port, "MeterID": meterID})
	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, "Received RestoreMetersFromDb and 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.Debugw(ctx, "Retrieved Meter", log.Fields{"Meter": meter.Name})
		m.AddMeter(&meter)
		if meter.ID > m.LastMeterID {
			m.LastMeterID = meter.ID
		}
	}
	logger.Debugw(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) {
	logger.Infow(ctx, "Add the meter profile name as key", log.Fields{"MeterConfig": cfg})
	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) {
	logger.Debugw(ctx, "Update the meter profile name as key", log.Fields{"MeterConfig": cfg})
	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) {
	logger.Debugw(ctx, "Get Meter by Profile id", log.Fields{"ID": id})
	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) {
	logger.Debugw(ctx, "Get Meter by Meter id", log.Fields{"MeterID": meterID})
	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) {
	logger.Debugw(ctx, "Delete meter from device", log.Fields{"Id": vm.ID, "Port": port, "Device": device})
	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 {
	logger.Debugw(ctx, "Delete meter profile", log.Fields{"Name": name})
	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
}
