package v1

import (
	"context"

	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ = Describe("NetworkPeer", func() {

	Context("Create NetworkPeer", func() {

		It("should reject networkpeer with absent source network", func() {

			np := &NetworkPeer{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "networkpeer-" + RandomString(5),
					Namespace: "default",
				},
				Spec: NetworkPeerSpec{
					Target: Target{
						AWS: &AWS{
							AccountID:  "123",
							VpcID:      "vpc-" + RandomString(17),
							PeerCIDR:   "10.0.0.1/32",
							PeerRegion: "us-east-2",
						},
					},
				},
			}

			err := k8sClient.Create(context.TODO(), np)
			Expect(err).ToNot(Succeed())
		})

		It("should reject networkpeer with absent target network", func() {

			np := &NetworkPeer{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "networkpeer-" + RandomString(5),
					Namespace: "default",
				},
				Spec: NetworkPeerSpec{
					Source: "network-123",
				},
			}

			err := k8sClient.Create(context.TODO(), np)
			Expect(err).ToNot(Succeed())
		})

		It("should reject networkpeer with two target network", func() {

			np := &NetworkPeer{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "networkpeer-" + RandomString(5),
					Namespace: "default",
				},
				Spec: NetworkPeerSpec{
					Source: "network-123",
					Target: Target{
						AWS: &AWS{
							AccountID:  "123",
							VpcID:      "vpc-" + RandomString(17),
							PeerCIDR:   "10.0.0.1/32",
							PeerRegion: "us-east-2",
						},
						GCP: &GCP{
							ProjectID:   "my-peer-123456",
							PeerNetwork: "vpc-123456",
						},
					},
				},
			}

			err := k8sClient.Create(context.TODO(), np)
			Expect(err).ToNot(Succeed())
		})

		It("should contains provider type and region label", func() {
			pt, _, nt, _ := prepareCluster()
			np := &NetworkPeer{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "networkpeer-" + RandomString(5),
					Namespace: nt.Namespace,
				},
				Spec: NetworkPeerSpec{
					Source: nt.Name,
					Target: Target{
						AWS: &AWS{
							AccountID:  "123",
							VpcID:      "vpc-" + RandomString(17),
							PeerCIDR:   "10.0.0.1/32",
							PeerRegion: "us-east-2",
						},
					},
				},
			}

			err := k8sClient.Create(context.TODO(), np)
			Expect(err).To(BeNil())
			Expect(np.Labels[ProviderTypeLabel]).To(Equal(pt.Name))
			Expect(np.Labels[RegionLabel]).To(Equal(nt.Spec.Region))
		})

		It("should create peering successful when provider is eks", func() {
			// prepare eks provider
			_, _, nt, _ := prepareCluster(option{providerName: ProviderTypeEKS})
			np := &NetworkPeer{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "networkpeer-" + RandomString(5),
					Namespace: nt.Namespace,
				},
				Spec: NetworkPeerSpec{
					Source: nt.Name,
					Target: Target{
						AWS: &AWS{
							AccountID:  "123",
							VpcID:      "vpc-" + RandomString(17),
							PeerCIDR:   "10.0.0.1/32",
							PeerRegion: "us-east-2",
						},
					},
				},
			}

			err := k8sClient.Create(context.TODO(), np)
			Expect(err).To(BeNil())
		})

		It("should reject gcp network peering with aws vpc", func() {
			// prepare gcp provider
			_, _, nt, _ := prepareCluster(option{providerName: ProviderTypeGCP})
			np := &NetworkPeer{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "networkpeer-" + RandomString(5),
					Namespace: nt.Namespace,
				},
				Spec: NetworkPeerSpec{
					Source: nt.Name,
					Target: Target{
						AWS: &AWS{
							AccountID:  "123",
							VpcID:      "vpc-" + RandomString(17),
							PeerCIDR:   "10.0.0.1/32",
							PeerRegion: "us-east-2",
						},
					},
				},
			}

			err := k8sClient.Create(context.TODO(), np)
			Expect(err).ToNot(Succeed())
		})
	})
})
