package framework

import (
	"fmt"
)

// TODO: hot reload, need to stop and re-create related running things

// TODO: yaml/json mapping
type ScalerConfig struct {
	UniqName       ScalerUniqName
	ScalerMeta     UnattachedScalerMeta
	InputUniqName  string
	OutputUniqName string
	DefaultConfig  ConfigData
	InputConfig    ConfigData
	OutputConfig   ConfigData
}

func (this *ScalerConfig) String() string {
	return fmt.Sprintf("UniqName:%s;%s;InputUniqName:%s;OutputUniqName:%s",
		this.UniqName,
		this.ScalerMeta.String(),
		this.InputUniqName,
		this.OutputUniqName)
}

func (this *ScalerConfig) autoGenUniqName() ScalerUniqName {
	if this.UniqName == "" {
		this.UniqName = ScalerUniqName(fmt.Sprintf("%s;InputName:%s;OutputName:%s",
			this.ScalerMeta.String(), this.InputUniqName, this.OutputUniqName))
	}
	return this.UniqName
}

type ScalerConfigManager struct {
	eventReceiver EventReceiver
	configs       map[ScalerUniqName]ScalerConfig
}

func NewScalerConfigManager(eventReceiver EventReceiver) *ScalerConfigManager {
	return &ScalerConfigManager{
		eventReceiver: eventReceiver,
		configs:       make(map[ScalerUniqName]ScalerConfig),
	}
}

func (this *ScalerConfigManager) Get(uniqName ScalerUniqName) (ScalerConfig, bool) {
	config, ok := this.configs[uniqName]
	return config, ok
}

func (this *ScalerConfigManager) Add(config *ScalerConfig, allowReplace bool) bool {
	uniqName := config.autoGenUniqName()
	_, ok := this.configs[uniqName]
	if ok {
		if !allowReplace {
			return false
		}
	}
	this.configs[uniqName] = *config
	this.eventReceiver.OnEvent(
		EventScalerConfigManagerAddItem,
		EventDataWithName("ScalerConfigItem", CloneableString(config.String())))
	return true
}

var ScalerConfigMockItem0 = &ScalerConfig{
	UniqName:       "ScalerConfigMockItem0",
	ScalerMeta:     ClusterScalerMockEmptyMeta.ScalerMeta,
	InputUniqName:  InputProviderConfigMockItem0.UniqName,
	OutputUniqName: OutputConfigMockItem0.UniqName,
	DefaultConfig:  nil,
}

var ScalerConfigMockItem1 = &ScalerConfig{
	UniqName:       "ScalerConfigMockItem1",
	ScalerMeta:     ClusterScalerPhasedComponentScalerMockV1Meta.ScalerMeta,
	InputUniqName:  InputProviderConfigMockItem1.UniqName,
	OutputUniqName: OutputConfigMockItem0.UniqName,
	DefaultConfig:  nil,
}

func (this *ScalerConfigManager) LoadMockConfig() {
	this.Add(ScalerConfigMockItem0, true)
	this.Add(ScalerConfigMockItem1, true)
}

func (this *ScalerConfigManager) LoadFromFile() error {
	// TODO: impl
	return nil
}
