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

package util

import (
	"testing"

	. "github.com/onsi/gomega"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/event"
)

func TestCheckNetworkRegion(t *testing.T) {
	type args struct {
		region string
		obj    *cloudv1.Network
	}
	cases := []struct {
		name        string
		args        args
		expectErr   bool
		matchRegion bool
	}{
		{
			name: "region is empty",
			args: args{
				region: "",
				obj: &cloudv1.Network{
					Spec: cloudv1.NetworkSpec{
						Region: "",
					},
				},
			},
			expectErr: true,
		},
		{
			name: "region match",
			args: args{
				region: "region",
				obj: &cloudv1.Network{
					Spec: cloudv1.NetworkSpec{
						Region: "region",
					},
				},
			},
			expectErr:   false,
			matchRegion: true,
		},
		{
			name: "region not match",
			args: args{
				region: "foo",
				obj: &cloudv1.Network{
					Spec: cloudv1.NetworkSpec{
						Region: "bar",
					},
				},
			},
			expectErr:   false,
			matchRegion: false,
		},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			g := NewGomegaWithT(t)
			ok, err := CheckNetworkRegion(tc.args.region, tc.args.obj)
			if tc.expectErr {
				g.Expect(err).To(HaveOccurred())
				return
			}
			g.Expect(ok).To(Equal(tc.matchRegion))
		})
	}
}

func TestRegionalPredicate(t *testing.T) {
	type args struct {
		region string
		obj    *cloudv1.Network
	}
	cases := []struct {
		name        string
		region      string
		obj         client.Object
		expectMatch bool
	}{
		{
			name: "region labe is empty",
			obj: &cloudv1.Network{
				Spec: cloudv1.NetworkSpec{
					Region: "",
				},
			},
			expectMatch: true,
		},
		{
			name:   "region match",
			region: "region",
			obj: &cloudv1.Network{
				ObjectMeta: metav1.ObjectMeta{
					Labels: map[string]string{
						regionalKey: "region",
					},
				},
			},
			expectMatch: true,
		},
		{
			name:   "region not match",
			region: "foo",
			obj: &cloudv1.Network{
				ObjectMeta: metav1.ObjectMeta{
					Labels: map[string]string{
						regionalKey: "bar",
					},
				},
			},
			expectMatch: false,
		},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			g := NewGomegaWithT(t)
			event := event.GenericEvent{
				Object: tc.obj,
			}
			if tc.expectMatch {
				g.Expect(RegionalPredicate(tc.region).Generic(event)).To(BeTrue())
				return
			}
			g.Expect(RegionalPredicate(tc.region).Generic(event)).NotTo(BeTrue())
		})
	}
}
