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

package eks

import (
	"context"
	"testing"

	ec2v1alpha1 "github.com/crossplane-contrib/provider-aws/apis/ec2/v1alpha1"
	"github.com/crossplane-contrib/provider-aws/apis/eks/manualv1alpha1"
	"github.com/crossplane-contrib/provider-aws/apis/eks/v1beta1"
	. "github.com/onsi/gomega"
	"github.com/tidbcloud/eks-provider/api/v1alpha1"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/infra-provider/pkg/consts"
	"github.com/tidbcloud/infra-provider/pkg/namer"

	"github.com/tidbcloud/eks-provider/controllers/network/task"
	"github.com/tidbcloud/infra-provider/pkg/k8s"
	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"
)

var (
	fakeNodeGroupNetwork     cloudv1.Network
	fakeNodeGroupCluster     task.ClusterIdentifier
	fakeNodeGroupNetworkSpec v1alpha1.EKSNetworkSpec
)

func init() {
	fakeNodeGroupNetwork.Name = "fake-nodegroupr"
	fakeNodeGroupNetwork.Namespace = "fake-ns"
	fakeNodeGroupCluster = task.NewEKSClusterIdentifier(&v1beta1.Cluster{})
	fakeNodeGroupNetworkSpec.NodeRoleArn = "fake-node-role-arn"
}

func TestNodeGroupCreate(t *testing.T) {
	cases := map[string]struct {
		context   *task.Context
		objs      []client.Object
		expectErr bool
	}{
		"create-success": {
			context: &task.Context{
				Remote:         &k8s.EmptyGetter{},
				Namer:          namer.NewNamer(),
				Network:        &fakeNodeGroupNetwork,
				Cluster:        fakeNodeGroupCluster,
				EKSNetworkSpec: &fakeNodeGroupNetworkSpec,
			},
			expectErr: false,
		},
		"already-created": {
			context: &task.Context{
				Remote:         &k8s.EmptyGetter{},
				Namer:          namer.NewNamer(),
				Network:        &fakeNodeGroupNetwork,
				Cluster:        fakeNodeGroupCluster,
				EKSNetworkSpec: &fakeNodeGroupNetworkSpec,
			},
			objs: []client.Object{
				&manualv1alpha1.NodeGroup{
					ObjectMeta: metav1.ObjectMeta{
						Name: namer.UniqueIdentifier(fakeNodeGroupNetwork.ObjectMeta),
					},
				},
			},
			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(manualv1alpha1.SchemeBuilder.AddToScheme(s)).To(Succeed())
			g.Expect(ec2v1alpha1.SchemeBuilder.AddToScheme(s)).To(Succeed())
			cli := fake.NewClientBuilder().WithScheme(s).WithObjects(tc.objs...).Build()
			tc.context.Local = cli
			task := NewNodegroup(tc.context)
			res := task.Create(context.TODO())
			if !tc.expectErr {
				g.Expect(res.Error()).To(Succeed())
			} else {
				g.Expect(res.Error()).NotTo(Succeed())
				return
			}
			ng := &manualv1alpha1.NodeGroup{}
			g.Expect(cli.Get(context.TODO(), client.ObjectKey{Name: namer.UniqueIdentifier(fakeNodeGroupNetwork.ObjectMeta, namer.WithPrefix(consts.TiDBCloudPrefix))}, ng)).To(Succeed())
			g.Expect(ng.Spec.ForProvider.Tags).To(HaveKeyWithValue(consts.TagKeyCrossplaneVendor, consts.TagValCrossplaneVendor))
			g.Expect(ng.Spec.ForProvider.Labels).To(HaveKeyWithValue("tidbcloud.com/component", "shared"))
		})
	}
}
