package output_blackhole

import (
	"fmt"
	"sort"

	"github.com/tidbcloud/cluster-service-ng/pkg/autoscale/framework"
)

const OutputBlackholeIdStr framework.OutputType = "OutputBlackhole"

var OutputBlackholeMeta = framework.OutputMeta{
	Type:             OutputBlackholeIdStr,
	InterfaceVersion: framework.OutputInterfaceV1IdStr,
}

type OutputBlackholeConfig struct{}

func (c *OutputBlackholeConfig) FillBlankValuesFrom(another framework.ConfigData) framework.ConfigData {
	return c
}

func (c *OutputBlackholeConfig) UniqStr() string {
	return "output-blackhole"
}

func ParseConfig(cfg map[string]any) (framework.ConfigData, error) {
	return &OutputBlackholeConfig{}, nil
}

type OutputBlackhole struct {
	eventReceiver framework.EventReceiver
}

func NewOutputBlackhole(eventReceiver framework.EventReceiver, _ framework.ConfigData) (any, error) {
	return &OutputBlackhole{
		eventReceiver: eventReceiver,
	}, nil
}

func (o *OutputBlackhole) SetNewClusterTopology(
	clusterId framework.ClusterId,
	current framework.ClusterTopologyV1,
	expected framework.ClusterTopologyV1,
) error {
	o.eventReceiver.OnEvent(
		EventOutputBlackholeSetNewClusterTopology,
		framework.EventDataWithName("ClusterId", framework.CloneableString(clusterId)),
		framework.EventDataWithName("CurrentTopology", framework.CloneableString(TopologyToString(current))),
		framework.EventDataWithName("ExpectedTopology", framework.CloneableString(TopologyToString(expected))),
	)
	return nil
}

func TopologyToString(topology framework.ClusterTopologyV1) string {
	if len(topology) == 0 {
		return "{}"
	}
	keys := make([]framework.InstanceName, 0, len(topology))
	for k := range topology {
		keys = append(keys, k)
	}
	sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })

	result := "{"
	for i, name := range keys {
		if i > 0 {
			result += ", "
		}
		comp := topology[name]
		result += fmt.Sprintf("%s:%s:%s:%d", name, comp.Name, comp.Type, comp.Replicas)
	}
	result += "}"
	return result
}

const EventOutputBlackholeSetNewClusterTopology framework.EventName = "OutputBlackhole.SetNewClusterTopology"
