package resourcemanager

import (
	"context"

	"github.com/tidbcloud/observability/pkg/common/errors"
	batchv1 "k8s.io/api/batch/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

type jobReaderWriter struct {
	kubeClient kubernetes.Interface
}

func (j jobReaderWriter) Create(ctx context.Context, job *batchv1.Job) error {
	_, err := j.kubeClient.BatchV1().Jobs(job.Namespace).Create(ctx, job, metav1.CreateOptions{})

	if err != nil && apierrors.IsAlreadyExists(err) {
		return errors.New(errors.DuplicatedEvaluationName, err.Error())
	}

	return WrapClientError(err)
}

func (j jobReaderWriter) Get(ctx context.Context, ns, name string) (*batchv1.Job, error) {
	job, err := j.kubeClient.BatchV1().
		Jobs(ns).
		Get(ctx, name, metav1.GetOptions{})

	if err == nil {
		return job, nil
	} else if client.IgnoreNotFound(err) == nil {
		return nil, errors.New(errors.EvaluationNotFound, "")
	} else {
		return nil, WrapClientError(err)
	}
}

func (j jobReaderWriter) IsJobExists(ctx context.Context, ns, name string) (bool, error) {
	_, err := j.kubeClient.BatchV1().
		Jobs(ns).
		Get(ctx, name, metav1.GetOptions{})

	if err == nil {
		return true, nil
	} else if client.IgnoreNotFound(err) == nil {
		return false, nil
	} else {
		return false, WrapClientError(err)
	}
}

func (j jobReaderWriter) Delete(ctx context.Context, ns string, name string) (*batchv1.Job, error) {
	job, err := j.Get(ctx, ns, name)
	if err != nil {
		return job, err
	}
	err = j.kubeClient.BatchV1().
		Jobs(ns).
		Delete(ctx, name, metav1.DeleteOptions{})
	return job, err
}
