package config

import "fmt"

// O11yNodePoolConfigValues holds one resolved o11y pool after applying
// root-config overrides on top of provider defaults.
type O11yNodePoolConfigValues struct {
	InstanceType     string
	MinSize          int
	MaxSize          int
	SystemVolumeSize int64
	AMIType          string
	CPU              int
	MemoryGi         int
}

// GetO11yNodePools resolves o11y pool settings from root-config with provider defaults.
// Unlike GetAdminNodeConfig, there is no APPBox CR override layer.
// Returns nil when Enabled is false (callers should create nothing and clean up stale pools).
// Callers should pass defaultMinSize=0 so disabled/idle pools do not burn capacity.
// Duplicate InstanceType entries keep the first; later duplicates are skipped.
// InstanceType is required on each pool (no provider default).
// Returns an error if any pool has empty InstanceType or non-positive CPU/MemoryGi.
func GetO11yNodePools(
	cfg O11yNodeConfig,
	defaultMinSize int,
	defaultMaxSize int,
	defaultSystemVolumeSize int64,
) ([]O11yNodePoolConfigValues, error) {
	if !cfg.Enabled {
		return nil, nil
	}

	seen := make(map[string]struct{}, len(cfg.Pools))
	result := make([]O11yNodePoolConfigValues, 0, len(cfg.Pools))
	for i, pool := range cfg.Pools {
		if pool.InstanceType == "" {
			return nil, fmt.Errorf("o11yNodeConfig.pools[%d]: instanceType is required", i)
		}
		if pool.CPU <= 0 || pool.MemoryGi <= 0 {
			return nil, fmt.Errorf("o11yNodeConfig.pools[%d]: cpu and memoryGi must be positive", i)
		}

		resolved := O11yNodePoolConfigValues{
			InstanceType:     pool.InstanceType,
			MinSize:          defaultMinSize,
			MaxSize:          defaultMaxSize,
			SystemVolumeSize: defaultSystemVolumeSize,
			AMIType:          pool.AMIType,
			CPU:              pool.CPU,
			MemoryGi:         pool.MemoryGi,
		}
		if pool.MaxSize != nil {
			resolved.MaxSize = int(*pool.MaxSize)
		}
		if pool.MinSize != nil {
			resolved.MinSize = int(*pool.MinSize)
		}
		if pool.SystemVolumeSize != nil {
			resolved.SystemVolumeSize = *pool.SystemVolumeSize
		}

		if _, dup := seen[resolved.InstanceType]; dup {
			continue
		}
		seen[resolved.InstanceType] = struct{}{}
		result = append(result, resolved)
	}
	return result, nil
}
