package task

import (
	"reflect"
	"testing"

	batchv1 "k8s.io/api/batch/v1"

	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

	"github.com/pingcap-inc/clinic/pkg/config"
)

type MockK8s struct {
	Jobs []batchv1.Job
	Err  error
}

func NewMockK8s(n int, err error) *MockK8s {
	job := make([]batchv1.Job, 0)
	for i := 0; i < n; i++ {
		job = append(job, batchv1.Job{})
	}
	return &MockK8s{
		Jobs: job,
		Err:  err,
	}
}

func (kc *MockK8s) ListJob(label map[string]string) []batchv1.Job {
	return kc.Jobs
}

func (kc *MockK8s) CreateJob(req *CreateJobRequest) error {
	return kc.Err
}

func (kc *MockK8s) CleanResource() {
}

func newUnstructured(apiVersion, kind, namespace, name string) *unstructured.Unstructured {
	return &unstructured.Unstructured{
		Object: map[string]any{
			"apiVersion": apiVersion,
			"kind":       kind,
			"metadata": map[string]any{
				// "namespace": namespace,
				"name": name,
			},
		},
	}
}

func TestK8sClientV1_ListJob(t *testing.T) {
	kc := config.K8sConfig{
		Namespace: "clinic",
		ImageName: "test-importer",
		Path:      "/Users/wuyulin/.kube/config",
		InCluster: false,
	}

	kcclient, err := NewK8sClient(kc)
	if err != nil {
		t.Error("init k8s client failed", err)
	}

	type caseListJobOption struct {
		kcclient K8sClient
		orgID    string
		param    map[string]string
		want     []string
	}

	testListJob := func(o *caseListJobOption) {
		if err := o.kcclient.CreateJob(&CreateJobRequest{
			OrganizationID: o.orgID,
			Concurrency:    1,
			PvcSize:        1,
			Param:          o.param,
		}); err != nil {
			t.Errorf("K8sClientV1.CreateJob() error = %v", err)
		}
		if got := o.kcclient.ListJob(improtJoblabel); !reflect.DeepEqual(got, o.want) {
			t.Errorf("K8sClientV1.ListJob() = %v, want %v", got, o.want)
		}
	}

	testListJob(&caseListJobOption{
		kcclient: kcclient,
		orgID:    "123",
		param:    map[string]string{"test": "xx"},
		want:     []string{"importer-123"},
	})
}

func TestK8sClientV1_CreateJob(t *testing.T) {
	kc := config.K8sConfig{
		Namespace: "clinic",
		ImageName: "test-importer",
		Path:      "/Users/wuyulin/.kube/config",
		InCluster: false,
	}

	kcclient, err := NewK8sClient(kc)
	if err != nil {
		t.Error("init k8s client failed", err)
	}

	type caseCreateJobOption struct {
		kcclient K8sClient
		orgID    string
		param    map[string]string
		wantErr  bool
	}

	testCreateJob := func(o *caseCreateJobOption) {
		if err := o.kcclient.CreateJob(&CreateJobRequest{
			OrganizationID: o.orgID,
			Concurrency:    1,
			PvcSize:        1,
			Param:          o.param,
		}); (err != nil) != o.wantErr {
			t.Errorf("K8sClientV1.CreateJob() error = %v, wantErr %v", err, o.wantErr)
		}
		// get, err := o.kcclient.Resource(schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "job"}).Namespace(kc.kconfig.Namespace).Get(context.TODO(), o.orgID, metav1.GetOptions{})
		// if err != nil || get == nil {
		// 	t.Errorf("K8sClientV1.CreateJob() error = %v, wantErr %v", err, o.wantErr)
		// }
	}
	testCreateJob(&caseCreateJobOption{
		kcclient: kcclient,
		orgID:    "123123",
		param:    map[string]string{"-f": "sdfasdf"},
		wantErr:  false,
	})
}
