/*
 *
 * Copyright 2020 gRPC 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 hierarchy

import (
	"testing"

	"github.com/google/go-cmp/cmp"
	"google.golang.org/grpc/attributes"
	"google.golang.org/grpc/resolver"
)

func TestGet(t *testing.T) {
	tests := []struct {
		name string
		addr resolver.Address
		want []string
	}{
		{
			name: "not set",
			addr: resolver.Address{},
			want: nil,
		},
		{
			name: "set",
			addr: resolver.Address{
				Attributes: attributes.New(pathKey, []string{"a", "b"}),
			},
			want: []string{"a", "b"},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Get(tt.addr); !cmp.Equal(got, tt.want) {
				t.Errorf("Get() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestSet(t *testing.T) {
	tests := []struct {
		name string
		addr resolver.Address
		path []string
	}{
		{
			name: "before is not set",
			addr: resolver.Address{},
			path: []string{"a", "b"},
		},
		{
			name: "before is set",
			addr: resolver.Address{
				Attributes: attributes.New(pathKey, []string{"before", "a", "b"}),
			},
			path: []string{"a", "b"},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			newAddr := Set(tt.addr, tt.path)
			newPath := Get(newAddr)
			if !cmp.Equal(newPath, tt.path) {
				t.Errorf("path after Set() = %v, want %v", newPath, tt.path)
			}
		})
	}
}

func TestGroup(t *testing.T) {
	tests := []struct {
		name  string
		addrs []resolver.Address
		want  map[string][]resolver.Address
	}{
		{
			name: "all with hierarchy",
			addrs: []resolver.Address{
				{Addr: "a0", Attributes: attributes.New(pathKey, []string{"a"})},
				{Addr: "a1", Attributes: attributes.New(pathKey, []string{"a"})},
				{Addr: "b0", Attributes: attributes.New(pathKey, []string{"b"})},
				{Addr: "b1", Attributes: attributes.New(pathKey, []string{"b"})},
			},
			want: map[string][]resolver.Address{
				"a": {
					{Addr: "a0", Attributes: attributes.New(pathKey, []string{})},
					{Addr: "a1", Attributes: attributes.New(pathKey, []string{})},
				},
				"b": {
					{Addr: "b0", Attributes: attributes.New(pathKey, []string{})},
					{Addr: "b1", Attributes: attributes.New(pathKey, []string{})},
				},
			},
		},
		{
			// Addresses without hierarchy are ignored.
			name: "without hierarchy",
			addrs: []resolver.Address{
				{Addr: "a0", Attributes: attributes.New(pathKey, []string{"a"})},
				{Addr: "a1", Attributes: attributes.New(pathKey, []string{"a"})},
				{Addr: "b0", Attributes: nil},
				{Addr: "b1", Attributes: nil},
			},
			want: map[string][]resolver.Address{
				"a": {
					{Addr: "a0", Attributes: attributes.New(pathKey, []string{})},
					{Addr: "a1", Attributes: attributes.New(pathKey, []string{})},
				},
			},
		},
		{
			// If hierarchy is set to a wrong type (which should never happen),
			// the address is ignored.
			name: "wrong type",
			addrs: []resolver.Address{
				{Addr: "a0", Attributes: attributes.New(pathKey, []string{"a"})},
				{Addr: "a1", Attributes: attributes.New(pathKey, []string{"a"})},
				{Addr: "b0", Attributes: attributes.New(pathKey, "b")},
				{Addr: "b1", Attributes: attributes.New(pathKey, 314)},
			},
			want: map[string][]resolver.Address{
				"a": {
					{Addr: "a0", Attributes: attributes.New(pathKey, []string{})},
					{Addr: "a1", Attributes: attributes.New(pathKey, []string{})},
				},
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Group(tt.addrs); !cmp.Equal(got, tt.want, cmp.AllowUnexported(attributes.Attributes{})) {
				t.Errorf("Group() = %v, want %v", got, tt.want)
				t.Errorf("diff: %v", cmp.Diff(got, tt.want, cmp.AllowUnexported(attributes.Attributes{})))
			}
		})
	}
}

func TestGroupE2E(t *testing.T) {
	hierarchy := map[string]map[string][]string{
		"p0": {
			"wt0": {"addr0", "addr1"},
			"wt1": {"addr2", "addr3"},
		},
		"p1": {
			"wt10": {"addr10", "addr11"},
			"wt11": {"addr12", "addr13"},
		},
	}

	var addrsWithHierarchy []resolver.Address
	for p, wts := range hierarchy {
		path1 := []string{p}
		for wt, addrs := range wts {
			path2 := append([]string(nil), path1...)
			path2 = append(path2, wt)
			for _, addr := range addrs {
				a := resolver.Address{
					Addr:       addr,
					Attributes: attributes.New(pathKey, path2),
				}
				addrsWithHierarchy = append(addrsWithHierarchy, a)
			}
		}
	}

	gotHierarchy := make(map[string]map[string][]string)
	for p1, wts := range Group(addrsWithHierarchy) {
		gotHierarchy[p1] = make(map[string][]string)
		for p2, addrs := range Group(wts) {
			for _, addr := range addrs {
				gotHierarchy[p1][p2] = append(gotHierarchy[p1][p2], addr.Addr)
			}
		}
	}

	if !cmp.Equal(gotHierarchy, hierarchy) {
		t.Errorf("diff: %v", cmp.Diff(gotHierarchy, hierarchy))
	}
}
