// Copyright Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package util

import (
	"testing"
)

import (
	. "github.com/onsi/gomega"
)

import (
	"github.com/apache/dubbo-go-pixiu/pkg/config/resource"
)

func TestGetResourceNameFromHost(t *testing.T) {
	g := NewWithT(t)

	// FQDN, same namespace
	g.Expect(GetResourceNameFromHost("default", "foo.default.svc.cluster.local")).To(Equal(resource.NewFullName("default", "foo")))
	// FQDN, cross namespace
	g.Expect(GetResourceNameFromHost("default", "foo.other.svc.cluster.local")).To(Equal(resource.NewFullName("other", "foo")))
	// short name
	g.Expect(GetResourceNameFromHost("default", "foo")).To(Equal(resource.NewFullName("default", "foo")))
	// bogus FQDN (gets treated like a short name)
	g.Expect(GetResourceNameFromHost("default", "foo.svc.cluster.local")).To(Equal(resource.NewFullName("default", "foo.svc.cluster.local")))
}

func TestGetScopedFqdnHostname(t *testing.T) {
	g := NewWithT(t)

	// FQDN, same namespace, local scope
	g.Expect(NewScopedFqdn("default", "default", "foo.default.svc.cluster.local")).To(Equal(ScopedFqdn("default/foo.default.svc.cluster.local")))
	// FQDN, cross namespace, local scope
	g.Expect(NewScopedFqdn("default", "other", "foo.default.svc.cluster.local")).To(Equal(ScopedFqdn("default/foo.default.svc.cluster.local")))
	// FQDN, same namespace, all namespaces scope
	g.Expect(NewScopedFqdn("*", "default", "foo.default.svc.cluster.local")).To(Equal(ScopedFqdn("*/foo.default.svc.cluster.local")))
	// FQDN, cross namespace, all namespaces scope
	g.Expect(NewScopedFqdn("*", "other", "foo.default.svc.cluster.local")).To(Equal(ScopedFqdn("*/foo.default.svc.cluster.local")))

	// short name, same namespace, local scope
	g.Expect(NewScopedFqdn("default", "default", "foo")).To(Equal(ScopedFqdn("default/foo.default.svc.cluster.local")))
	// short name, same namespace, all namespaces scope
	g.Expect(NewScopedFqdn("*", "default", "foo")).To(Equal(ScopedFqdn("*/foo.default.svc.cluster.local")))

	// wildcard, local scope
	g.Expect(NewScopedFqdn("foo", "foo", "*")).To(Equal(ScopedFqdn("foo/*")))
	// wildcard sub domain, local scope
	g.Expect(NewScopedFqdn("foo", "foo", "*.xyz.abc")).To(Equal(ScopedFqdn("foo/*.xyz.abc")))
	// wildcard, all namespaces scope
	g.Expect(NewScopedFqdn("*", "foo", "*")).To(Equal(ScopedFqdn("*/*")))
	// wildcard sub domain, all namespaces scope
	g.Expect(NewScopedFqdn("*", "foo", "*.xyz.abc")).To(Equal(ScopedFqdn("*/*.xyz.abc")))

	// external host, local scope
	g.Expect(NewScopedFqdn("foo", "foo", "xyz.abc")).To(Equal(ScopedFqdn("foo/xyz.abc")))
	// external host, all namespaces scope
	g.Expect(NewScopedFqdn("*", "foo", "xyz.abc")).To(Equal(ScopedFqdn("*/xyz.abc")))
}

func TestScopedFqdn_GetScopeAndFqdn(t *testing.T) {
	g := NewWithT(t)

	ns, fqdn := ScopedFqdn("default/reviews.default.svc.cluster.local").GetScopeAndFqdn()
	g.Expect(ns).To(Equal("default"))
	g.Expect(fqdn).To(Equal("reviews.default.svc.cluster.local"))

	ns, fqdn = ScopedFqdn("*/reviews.default.svc.cluster.local").GetScopeAndFqdn()
	g.Expect(ns).To(Equal("*"))
	g.Expect(fqdn).To(Equal("reviews.default.svc.cluster.local"))

	ns, fqdn = ScopedFqdn("foo/*.xyz.abc").GetScopeAndFqdn()
	g.Expect(ns).To(Equal("foo"))
	g.Expect(fqdn).To(Equal("*.xyz.abc"))
}

func TestScopedFqdn_InScopeOf(t *testing.T) {
	tests := []struct {
		ScFqdn    ScopedFqdn
		Namespace string
		Want      bool
	}{
		{"*/reviews.bookinfo.svc.cluster.local", "bookinfo", true},
		{"*/reviews.bookinfo.svc.cluster.local", "foo", true},
		{"./reviews.bookinfo.svc.cluster.local", "bookinfo", true},
		{"./reviews.bookinfo.svc.cluster.local", "foo", false},
		{"bookinfo/reviews.bookinfo.svc.cluster.local", "bookinfo", true},
		{"bookinfo/reviews.bookinfo.svc.cluster.local", "foo", false},
	}

	for _, test := range tests {
		if test.ScFqdn.InScopeOf(test.Namespace) != test.Want {
			t.Errorf("%s is in the scope of %s: %t. It should be %t", test.ScFqdn, test.Namespace, !test.Want, test.Want)
		}
	}
}
