//go:build unit || all
// +build unit all

package eks

import (
	"context"
	"testing"

	"github.com/crossplane-contrib/provider-aws/apis/eks/v1beta1"
	. "github.com/onsi/gomega"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/client-go/kubernetes/scheme"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"

	"github.com/tidbcloud/eks-provider/api/v1alpha1"
	"github.com/tidbcloud/eks-provider/controllers/network/task"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/infra-provider/pkg/config"
	"github.com/tidbcloud/infra-provider/pkg/consts"
	"github.com/tidbcloud/infra-provider/pkg/namer"
)

var (
	fakeEKSNetwork     cloudv1.Network
	fakeEKSNetworkSpec v1alpha1.EKSNetworkSpec
)

func init() {
	fakeEKSNetwork.Name = "fake-eks-cluster"
	fakeEKSNetwork.Namespace = "fake-eks-cluster-namespace"
}

func TestEKSCreate(t *testing.T) {
	cases := map[string]struct {
		context   *task.Context
		objs      []client.Object
		expectErr bool
	}{
		"create-success": {
			context: &task.Context{
				Namer:          namer.NewNamer(),
				Network:        &fakeEKSNetwork,
				EKSNetworkSpec: &fakeEKSNetworkSpec,
				Config: config.RootConfig{
					ControllerConfig: config.ControllerConfig{
						Network: config.NetworkConfig{
							K8sVersion: "v1.21",
						},
					},
				},
			},
			expectErr: false,
		},
		"already-created": {
			context: &task.Context{
				Namer:          namer.NewNamer(),
				Network:        &fakeEKSNetwork,
				EKSNetworkSpec: &fakeEKSNetworkSpec,
				Config: config.RootConfig{
					ControllerConfig: config.ControllerConfig{
						Network: config.NetworkConfig{
							K8sVersion: "v1.21",
						},
					},
				},
			},
			objs: []client.Object{
				&v1beta1.Cluster{
					TypeMeta: metav1.TypeMeta{
						APIVersion: "eks.aws.crossplane.io/v1beta1",
						Kind:       "Cluster",
					},
					ObjectMeta: metav1.ObjectMeta{
						Name: namer.LegacyBuildClusterNameByNetwork(&fakeEKSNetwork),
					},
				},
			},
			expectErr: false,
		},
	}
	for name, tc := range cases {
		t.Run(name, func(t *testing.T) {
			g := NewGomegaWithT(t)
			s := runtime.NewScheme()
			g.Expect(scheme.AddToScheme(s)).To(Succeed())
			g.Expect(v1beta1.SchemeBuilder.AddToScheme(s)).To(Succeed())
			cli := fake.NewClientBuilder().WithScheme(s).WithObjects(tc.objs...).Build()
			tc.context.Local = cli
			task := NewEKS(tc.context, nil)
			res := task.Create(context.TODO())
			if !tc.expectErr {
				g.Expect(res.Error()).To(Succeed())
			} else {
				g.Expect(res.Error()).NotTo(Succeed())
				return
			}
			eks := &v1beta1.Cluster{}
			g.Expect(cli.Get(context.TODO(), client.ObjectKey{Name: namer.LegacyBuildClusterNameByNetwork(&fakeEKSNetwork)}, eks)).To(Succeed())
			g.Expect(eks.Spec.ForProvider.Tags).To(HaveKeyWithValue(consts.TagKeyCrossplaneVendor, consts.TagValCrossplaneVendor))
		})
	}
}
