// 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 listenertest

import (
	"fmt"
)

import (
	listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
	hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
)

import (
	xdsfilters "github.com/apache/dubbo-go-pixiu/pilot/pkg/xds/filters"
	"github.com/apache/dubbo-go-pixiu/pilot/test/xdstest"
	"github.com/apache/dubbo-go-pixiu/pkg/test"
	"github.com/apache/dubbo-go-pixiu/pkg/test/util/assert"
	"github.com/apache/dubbo-go-pixiu/pkg/util/sets"
)

type ListenersTest struct {
	// Match listener by name
	Name string
	// Match listener by port
	Port uint32

	// Listener assertions
	Listener ListenerTest
}

// ListenerTest provides a struct for defining expectations for a listener
type ListenerTest struct {
	// Assert the listener contains these filter chains (in order, if TotalMatch)
	FilterChains []FilterChainTest

	// Assert the listener contains these ListenerFilters (in order, if TotalMatch)
	Filters []string

	// TotalMatch will require that the all elements exactly match (eg, if I have 3 elements in the
	// check, the listener must as well). Otherwise, we only validate the assertions we provided are
	// present.
	TotalMatch bool
}

type FilterChainTest struct {
	// Match a filter chain by name
	Name string
	// Match filter chain by 'type'. This can be important since Name is currently not unique
	Type FilterChainType
	// Port the filter chain matches
	Port uint32

	NetworkFilters []string
	HTTPFilters    []string

	ValidateHCM func(t test.Failer, hcm *hcm.HttpConnectionManager)

	TotalMatch bool
}

type FilterChainType string

const (
	PlainTCP    FilterChainType = "plaintext TCP"
	PlainHTTP   FilterChainType = "plaintext HTTP"
	StandardTLS FilterChainType = "TLS"
	MTLSTCP     FilterChainType = "mTLS TCP"
	MTLSHTTP    FilterChainType = "mTLS HTTP"
	Unknown     FilterChainType = "unknown"
)

func classifyFilterChain(have *listener.FilterChain) FilterChainType {
	fcm := have.GetFilterChainMatch()
	alpn := sets.New(fcm.GetApplicationProtocols()...)
	switch fcm.GetTransportProtocol() {
	case xdsfilters.TLSTransportProtocol:
		if alpn.Contains("istio-http/1.1") {
			return MTLSHTTP
		}
		if alpn.Contains("istio") {
			return MTLSTCP
		}
		return StandardTLS
	case xdsfilters.RawBufferTransportProtocol:
		if alpn.Contains("http/1.1") {
			return PlainHTTP
		}
		return PlainTCP
	default:
		return Unknown
	}
}

func VerifyListeners(t test.Failer, listeners []*listener.Listener, lt ListenersTest) {
	t.Helper()
	for _, l := range listeners {
		if lt.Name != "" && lt.Name != l.Name {
			continue
		}
		if lt.Port != 0 && lt.Port != l.Address.GetSocketAddress().GetPortValue() {
			continue
		}
		// It was a match, run assertions
		VerifyListener(t, l, lt.Listener)
	}
}

func VerifyListener(t test.Failer, l *listener.Listener, lt ListenerTest) {
	t.Helper()
	haveFilters := []string{}
	for _, lf := range l.ListenerFilters {
		haveFilters = append(haveFilters, lf.Name)
	}

	// Check ListenerFilters

	if lt.Filters != nil {
		if lt.TotalMatch {
			assert.Equal(t, lt.Filters, haveFilters, l.Name+": listener filters should be equal")
		} else {
			if missing := sets.New(lt.Filters...).Difference(sets.New(haveFilters...)).SortedList(); len(missing) > 0 {
				t.Fatalf("%v: missing listener filters: %v", l.Name, missing)
			}
		}
	}

	// Check FilterChains
	if lt.FilterChains != nil {
		if lt.TotalMatch {
			// First check they are the same size
			if len(lt.FilterChains) != len(l.FilterChains) {
				want := []string{}
				for _, n := range lt.FilterChains {
					want = append(want, n.Name)
				}
				t.Fatalf("didn't match filter chains, have names %v, expected %v", xdstest.ExtractFilterChainNames(l), want)
			}
			// Now check they are equivalent
			for i := range lt.FilterChains {
				have := l.FilterChains[i]
				want := lt.FilterChains[i]

				VerifyFilterChain(t, have, want)
			}
		} else {
			for _, want := range lt.FilterChains {
				found := 0
				for _, have := range l.FilterChains {
					if want.Name != "" && want.Name != have.Name {
						continue
					}
					haveType := classifyFilterChain(have)
					if want.Type != "" && want.Type != haveType {
						continue
					}
					if want.Port != 0 && want.Port != have.GetFilterChainMatch().GetDestinationPort().GetValue() {
						continue
					}
					found++
					VerifyFilterChain(t, have, want)
				}
				if found == 0 {
					t.Fatalf("No matching chain found for %+v", want)
				}
				if found > 1 {
					t.Logf("warning: multiple matching chains found for %+v", want)
				}
			}
		}
	}
}

func VerifyFilterChain(t test.Failer, have *listener.FilterChain, want FilterChainTest) {
	t.Helper()
	haveType := classifyFilterChain(have)
	context := func(s string) string {
		return fmt.Sprintf("%v/%v: %v", have.Name, haveType, s)
	}
	if want.Name != "" {
		assert.Equal(t, want.Name, have.Name, context("name should be equal"))
	}
	if want.Type != "" {
		assert.Equal(t, want.Type, haveType, context("type should be equal"))
	}
	if want.Port != 0 {
		assert.Equal(t, want.Port, have.GetFilterChainMatch().GetDestinationPort().GetValue(), context("port should be equal"))
	}
	haveNetwork, haveHTTP := xdstest.ExtractFilterNames(t, have)
	if want.TotalMatch {
		if want.NetworkFilters != nil {
			assert.Equal(t, want.NetworkFilters, haveNetwork, context("network filters should be equal"))
		}
		if want.HTTPFilters != nil {
			assert.Equal(t, want.HTTPFilters, haveHTTP, context("http should be equal"))
		}
	} else {
		if missing := sets.New(want.NetworkFilters...).Difference(sets.New(haveNetwork...)).SortedList(); len(missing) > 0 {
			t.Fatalf("%v/%v: missing network filters: %v, have %v", have.Name, haveType, missing, haveNetwork)
		}
		if missing := sets.New(want.HTTPFilters...).Difference(sets.New(haveHTTP...)).SortedList(); len(missing) > 0 {
			t.Fatalf("%v/%v: missing network filters: %v, have %v", have.Name, haveType, missing, haveHTTP)
		}
	}
	if want.ValidateHCM != nil {
		want.ValidateHCM(t, xdstest.ExtractHTTPConnectionManager(t, have))
	}
}
