/*
* 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{"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
}
