package infraapi

import (
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
)

type RestoreParam struct {
	TenantID      uint64
	ProjectID     uint64
	ClusterID     uint64
	RestoreName   string
	ClusterName   string
	BackupName    string
	LogBackupName *string
	RestoredTS    *string

	Env                  []corev1.EnvVar
	ResourceRequirements *corev1.ResourceRequirements
	InstanceType         *string

	BucketInfo *RestoreBucketInfo
	Options    []string

	NodeRole      *string
	Configuration *cloudv1.DPConfiguration

	TagComponentValue   string
	TagEnvironmentValue string

	// CompactBackupName is the name of the sibling CompactBackup CR.
	// When non-empty, the cluster-server sets the annotation that enables
	// compaction-accelerated PiTR on the operator Restore CR.
	//
	// For PiTR only.
	CompactBackupName string
}

// In 3-layer arch, dataflow-svc will call the corresponding regional br-server for br task.
// We already provide the CloudProvider and Region info when calling regional br-server
// So we should deprecate CloudProvider, Region, Name, BackupPrefix and LogBackupPrefix fields,
// and use URI format SnapshotBackupStorage and LogBackupStorage fields instead
// Besides, the URI format makes it possible to use different buckets for snapshot and log backup.
type RestoreBucketInfo struct {
	// CloudProvider is the cloud provider of the bucket
	CloudProvider string
	// Region is the region of the bucket
	Region string
	// Name is the name of the bucket
	Name string
	// BackupPrefix is the prefix of the backup file.
	BackupPrefix string
	// LogBackupPrefix is the prefix of the log backup file.
	LogBackupPrefix string

	// SnapshotBackupStorage is the storage URI for snapshot backup
	SnapshotBackupStorage string
	// LogBackupStorage is the storage URI for log backup
	LogBackupStorage string
}

func SetRestoreDefaultEnv(restore *cloudv1.Restore) {
	for _, env := range restore.Spec.Env {
		if env.Name == GoMemLimitEnv {
			return
		}
	}
	// no GOMEMLIMIT in env, add it
	restore.Spec.Env = append(restore.Spec.Env, corev1.EnvVar{
		Name:  GoMemLimitEnv,
		Value: RestoreDefaultGoMemLimit,
	})
}

func SetRestoreDefaultResourceRequirements(restore *cloudv1.Restore) {
	if restore.Spec.ResourceRequirements == nil {
		restore.Spec.ResourceRequirements = &corev1.ResourceRequirements{}
	}
	if restore.Spec.ResourceRequirements.Limits == nil {
		restore.Spec.ResourceRequirements.Limits = make(corev1.ResourceList, 2)
	}
	// if no memory limits, add it
	if _, ok := restore.Spec.ResourceRequirements.Limits[corev1.ResourceMemory]; !ok {
		restore.Spec.ResourceRequirements.Limits[corev1.ResourceMemory] = resource.MustParse(RestoreDefaultMemoryLimit)
	}

	if restore.Spec.ResourceRequirements.Requests == nil {
		restore.Spec.ResourceRequirements.Requests = make(corev1.ResourceList, 2)
	}
	// if no memory requests, add it
	if _, ok := restore.Spec.ResourceRequirements.Requests[corev1.ResourceMemory]; !ok {
		restore.Spec.ResourceRequirements.Requests[corev1.ResourceMemory] = resource.MustParse(RestoreDefaultMemoryRequest)
	}
}
