package server

import (
	"fmt"
	"sort"
	"strings"

	"github.com/tidbcloud/cluster-service-ng/domain/entity"
)

func describeOptionsMap(optionsMap map[string][]string) string {
	if len(optionsMap) == 0 {
		return ""
	}
	keys := make([]string, 0, len(optionsMap))
	for key := range optionsMap {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	parts := make([]string, 0, len(keys))
	for _, key := range keys {
		parts = append(parts, fmt.Sprintf("%s=%s", key, strings.Join(optionsMap[key], ",")))
	}
	return strings.Join(parts, "; ")
}

func describeComponentSpecsByIDs(sharedPool *entity.SharedPool, componentIDs []string) string {
	if sharedPool == nil || len(componentIDs) == 0 {
		return ""
	}
	components := make([]*entity.Component, 0, len(componentIDs))
	for _, componentID := range componentIDs {
		for _, comp := range sharedPool.GetComponentGroups() {
			if comp.GetId() == componentID {
				components = append(components, comp)
				break
			}
		}
	}
	return describeComponents(components)
}

func describeComponents(components []*entity.Component) string {
	if len(components) == 0 {
		return ""
	}
	parts := make([]string, 0, len(components))
	for _, comp := range components {
		if comp == nil {
			continue
		}
		parts = append(parts, describeComponent(comp))
	}
	sort.Strings(parts)
	return strings.Join(parts, "; ")
}

func describeComponent(comp *entity.Component) string {
	if comp == nil {
		return "<nil>"
	}
	nodeQuota := comp.GetNodeQuota()
	if nodeQuota == nil || nodeQuota.GetNodeSpec() == nil {
		return fmt.Sprintf("%s/%s phase=%s", comp.GetComponentType().String(), comp.GetId(), comp.GetPhase().String())
	}
	return fmt.Sprintf("%s/%s phase=%s cpu=%d memGi=%d nodeCount=%d",
		comp.GetComponentType().String(),
		comp.GetId(),
		comp.GetPhase().String(),
		nodeQuota.GetNodeSpec().GetCpu(),
		nodeQuota.GetNodeSpec().GetMemoryGi(),
		nodeQuota.GetNodeCount(),
	)
}

func requestUnitToString(ru *entity.RequestUnit) string {
	if ru == nil {
		return "<nil>"
	}
	return fmt.Sprintf("max=%d min=%d", ru.GetMax(), ru.GetMin())
}

func requestUnitProtoToString(ru *entity.RequestUnit) string {
	if ru == nil {
		return "<nil>"
	}
	return fmt.Sprintf("max=%d min=%d", ru.GetMax(), ru.GetMin())
}
