package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// InfraQuota defines the resource limits for this infrastructure account
type InfraQuota struct {
	// MaxCPU is the total number of cores allowed across all clusters
	// +optional
	MaxCPU int `json:"maxCpu,omitempty"`

	// MaxMemoryGB is the total RAM (in GB) allowed across all clusters
	// +optional
	MaxMemoryGB int `json:"maxMemoryGb,omitempty"`

	// MaxDiskGB is the total Storage (in GB) allowed across all clusters
	// +optional
	MaxDiskGB int `json:"maxDiskGb,omitempty"`
}

// InfraQuotaStatus tracks current usage
type InfraQuotaStatus struct {
	// UsedCPU is the sum of cores currently provisioned
	UsedCPU int `json:"usedCpu"`

	// UsedMemoryGB is the sum of RAM currently provisioned
	UsedMemoryGB int `json:"usedMemoryGb"`

	// UsedDiskGB tracks storage consumption
	UsedDiskGB int `json:"usedDiskGb"`
}

// ProviderRef points to the specific provider configuration (HBP or VBP)
type ProviderRef struct {
	// Kind is the type of resource being referenced (e.g., HarvesterBlueprint)
	// +required
	Kind string `json:"kind"`

	// Name is the name of resource being referenced
	// +required
	Name string `json:"name"`

	// APIGroup defaults to rig.appstack.io if not specified
	// +optional
	APIGroup string `json:"apiGroup,omitempty"`
}

// InfraBlueprintSpec defines the desired state of InfraBlueprint
type InfraBlueprintSpec struct {
	// RancherURL is the public URL of the Rancher Manager (e.g. https://rancher.example.com)
	// This is injected into the Helm Chart to register the cluster.
	// +required
	RancherURL string `json:"rancherUrl"`

	// CloudCredentialSecret is the name of the Secret containing the
	// master cloud credentials (e.g., kubeconfig or username/password).
	// +required
	CloudCredentialSecret string `json:"cloudCredentialSecret"`

	// ProviderRef points to the technical configuration (HarvesterBlueprint/VsphereBlueprint).
	// +required
	ProviderRef ProviderRef `json:"providerRef"`

	// Quota defines the maximum resources allocatable by this Infra.
	// +optional
	Quota InfraQuota `json:"quota,omitempty"`

	// UserData is the default cloud-init user data for all clusters in this Infra.
	// +optional
	UserData string `json:"userData,omitempty"`
}

// InfraBlueprintStatus defines the observed state of InfraBlueprint
type InfraBlueprintStatus struct {
	// Ready indicates the provider connection is verified
	Ready bool `json:"ready,omitempty"`

	// Usage tracks the current resource consumption
	Usage InfraQuotaStatus `json:"usage,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:shortName=ibp
// +kubebuilder:printcolumn:name="Ready",type="boolean",JSONPath=".status.ready"
// +kubebuilder:printcolumn:name="MaxCPU",type="integer",JSONPath=".spec.quota.maxCpu"
// +kubebuilder:printcolumn:name="UsedCPU",type="integer",JSONPath=".status.usage.usedCpu"
// +kubebuilder:printcolumn:name="MaxMem(GB)",type="integer",JSONPath=".spec.quota.maxMemoryGb"
// +kubebuilder:printcolumn:name="UsedMem(GB)",type="integer",JSONPath=".status.usage.usedMemoryGb"
// +kubebuilder:printcolumn:name="MaxDisk(GB)",type="integer",JSONPath=".spec.quota.maxDiskGb"
// +kubebuilder:printcolumn:name="UsedDisk(GB)",type="integer",JSONPath=".status.usage.usedDiskGb"
type InfraBlueprint struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   InfraBlueprintSpec   `json:"spec,omitempty"`
	Status InfraBlueprintStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// InfraBlueprintList contains a list of InfraBlueprint
type InfraBlueprintList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []InfraBlueprint `json:"items"`
}

func init() {
	SchemeBuilder.Register(&InfraBlueprint{}, &InfraBlueprintList{})
}
