package config

import (
	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
)

// AdminNodeConfigValues holds the resolved admin node configuration values
// after applying the three-level fallback logic.
type AdminNodeConfigValues struct {
	InstanceType            string
	MinSize                 int
	MaxSize                 int
	SystemVolumeSize        int64
	AdditionalInstanceTypes []string
}

// GetAdminNodeConfig extracts admin node configuration with three-level fallback:
// 1. APPBox CR spec (highest priority)
// 2. Config file (middle priority)
// 3. Provider defaults (lowest priority)
//
// Each field is evaluated independently, allowing mixed sources.
//
// Note: The APPBox CR is typically created by dataplane-controller, but operators
// may manually set AdminNodeConfig fields for specific instances. This function
// preserves these manual settings.
func GetAdminNodeConfig(
	crAdminNodeConfig v1alpha1.NodeConfig,
	configFileAdminNode AdminNodeConfig,
	defaultInstanceType string,
	defaultMinSize int,
	defaultMaxSize int,
	defaultSystemVolumeSize int64,
) AdminNodeConfigValues {
	result := AdminNodeConfigValues{
		InstanceType:     defaultInstanceType,
		MinSize:          defaultMinSize,
		MaxSize:          defaultMaxSize,
		SystemVolumeSize: defaultSystemVolumeSize,
	}

	// Instance type: CR spec -> config file -> default
	if crAdminNodeConfig.InstanceType != "" {
		result.InstanceType = crAdminNodeConfig.InstanceType
	} else if configFileAdminNode.InstanceType != nil && *configFileAdminNode.InstanceType != "" {
		result.InstanceType = *configFileAdminNode.InstanceType
	}

	// Max size: CR spec -> config file -> default
	if crAdminNodeConfig.MaxSize != nil {
		result.MaxSize = int(*crAdminNodeConfig.MaxSize)
	} else if configFileAdminNode.MaxSize != nil {
		result.MaxSize = int(*configFileAdminNode.MaxSize)
	}

	// Min size: CR spec -> config file -> default
	if crAdminNodeConfig.MinSize != nil {
		result.MinSize = int(*crAdminNodeConfig.MinSize)
	} else if configFileAdminNode.MinSize != nil {
		result.MinSize = int(*configFileAdminNode.MinSize)
	}

	// System volume size: CR spec -> config file -> default
	if crAdminNodeConfig.SystemVolumeSize != nil {
		result.SystemVolumeSize = *crAdminNodeConfig.SystemVolumeSize
	} else if configFileAdminNode.SystemVolumeSize != nil {
		result.SystemVolumeSize = *configFileAdminNode.SystemVolumeSize
	}

	// Additional instance types: CR spec -> config file
	if len(crAdminNodeConfig.AdditionalInstanceTypes) > 0 {
		result.AdditionalInstanceTypes = crAdminNodeConfig.AdditionalInstanceTypes
	} else {
		result.AdditionalInstanceTypes = configFileAdminNode.AdditionalInstanceTypes
	}

	return result
}
