package resourcemerge

import (
	"testing"

	appsv1 "k8s.io/api/apps/v1"
	"k8s.io/apimachinery/pkg/api/equality"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/utils/pointer"
)

func TestEnsureDeployment(t *testing.T) {
	labelSelector := metav1.LabelSelector{}
	tests := []struct {
		name     string
		existing appsv1.Deployment
		required appsv1.Deployment

		expectedModified bool
		expected         appsv1.Deployment
	}{
		{
			name: "different replica count",
			existing: appsv1.Deployment{
				Spec: appsv1.DeploymentSpec{
					Replicas: int32Pointer(2)}},
			required: appsv1.Deployment{
				Spec: appsv1.DeploymentSpec{
					Replicas: int32Pointer(3)}},

			expectedModified: true,
			expected: appsv1.Deployment{
				Spec: appsv1.DeploymentSpec{
					Replicas: int32Pointer(3)}},
		},
		{
			name: "same replica count",
			existing: appsv1.Deployment{
				Spec: appsv1.DeploymentSpec{
					Replicas: int32Pointer(2)}},
			required: appsv1.Deployment{
				Spec: appsv1.DeploymentSpec{
					Replicas: int32Pointer(2)}},

			expectedModified: false,
			expected: appsv1.Deployment{
				Spec: appsv1.DeploymentSpec{
					Replicas: int32Pointer(2)}},
		},
		{
			name:     "existing-selector-nil-required-selector-non-nil",
			existing: appsv1.Deployment{},
			required: appsv1.Deployment{
				Spec: appsv1.DeploymentSpec{
					Selector: &labelSelector}},

			expectedModified: true,
			expected: appsv1.Deployment{
				Spec: appsv1.DeploymentSpec{
					Selector: &labelSelector}},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			modified := pointer.BoolPtr(false)
			EnsureDeployment(modified, &test.existing, test.required)
			if *modified != test.expectedModified {
				t.Errorf("mismatch modified got: %v want: %v", *modified, test.expectedModified)
			}

			if !equality.Semantic.DeepEqual(test.existing, test.expected) {
				t.Errorf("mismatch Deployment got: %v want: %v", test.existing, test.expected)
			}
		})
	}
}

func int32Pointer(i int32) *int32 {
	return &i
}
