package k8sresource

import (
	"context"

	"github.com/pingcap/errors"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/types"
	"sigs.k8s.io/controller-runtime/pkg/client"

	bizerr "github.com/tidbcloud/infra-provider/regional-server/pkg/common/errors"
)

func getUnstructured(
	ctx context.Context,
	cli client.Reader,
	gvk schema.GroupVersionKind,
	namespace, name string,
) (*unstructured.Unstructured, error) {
	obj := &unstructured.Unstructured{}
	obj.SetGroupVersionKind(gvk)
	key := types.NamespacedName{Name: name}
	if namespace != "" {
		key.Namespace = namespace
	}
	if err := cli.Get(ctx, key, obj); err != nil {
		if apierrors.IsNotFound(err) {
			return nil, bizerr.New(bizerr.ResourceNotFound, err.Error())
		}
		return nil, bizerr.New(bizerr.K8SClientError, errors.Wrap(err, "get resource").Error())
	}
	return obj, nil
}

func listUnstructured(
	ctx context.Context,
	cli client.Reader,
	gvk schema.GroupVersionKind,
	opts ...client.ListOption,
) (*unstructured.UnstructuredList, error) {
	list := &unstructured.UnstructuredList{}
	list.SetGroupVersionKind(gvk.GroupVersion().WithKind(gvk.Kind + "List"))
	if err := cli.List(ctx, list, opts...); err != nil {
		if apierrors.IsNotFound(err) {
			return nil, bizerr.New(bizerr.ResourceNotFound, err.Error())
		}
		return nil, bizerr.New(bizerr.K8SClientError, errors.Wrap(err, "list resources").Error())
	}
	return list, nil
}
