package gke

import (
	"context"

	corev1 "k8s.io/api/core/v1"
	storagev1 "k8s.io/api/storage/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/utils/ptr"

	"github.com/tidbcloud/eks-provider/controllers/imports/task"
	"github.com/tidbcloud/infra-provider/pkg/consts"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/k8s"
)

type StorageClass struct {
	*task.BaseTask
	storageClass string
}

// NewStorageClass creates customized storage classes with parameters specified from infra-api.
func NewStorageClass(ctx *task.Context, storageClass string) *StorageClass {
	return &StorageClass{
		BaseTask:     &task.BaseTask{Context: ctx},
		storageClass: storageClass,
	}
}

func (t *StorageClass) Name() string {
	return "StorageClass"
}

func (t *StorageClass) Create(ctx context.Context) deploy.Result {
	if t.Import.Spec.StorageRequest == "" {
		return deploy.Done()
	}
	clusterCli := t.EnvProvider.GetClient()
	sc := t.describeStorageClass()
	t.Logger.Info("try to create storageclass in dataplane gke", "sc", sc.Name)
	return deploy.ErrorOrDone(k8s.CreateIfNotExist(ctx, clusterCli, sc))
}

func (t *StorageClass) describeStorageClass() *storagev1.StorageClass {
	bindingMode := storagev1.VolumeBindingWaitForFirstConsumer
	reclaimPolicy := corev1.PersistentVolumeReclaimDelete
	sc := &storagev1.StorageClass{
		ObjectMeta: metav1.ObjectMeta{
			Name: t.storageClass,
		},
		VolumeBindingMode:    &bindingMode,
		AllowVolumeExpansion: ptr.To(true),
		ReclaimPolicy:        &reclaimPolicy,
		Provisioner:          "pd.csi.storage.gke.io",
		Parameters: map[string]string{
			"csi.storage.k8s.io/fstype": "ext4",
			"type":                      consts.GCPVolumeTypePDBalanced,
		},
		MountOptions: []string{"nodelalloc,noatime"},
	}
	return sc
}
