// +build !solaris

package daemon

import (
	"reflect"
	"sort"
	"testing"
	"time"

	"github.com/docker/docker/daemon/config"
	"github.com/docker/docker/pkg/discovery"
	_ "github.com/docker/docker/pkg/discovery/memory"
	"github.com/docker/docker/registry"
	"github.com/stretchr/testify/assert"
)

func TestDaemonReloadLabels(t *testing.T) {
	daemon := &Daemon{}
	daemon.configStore = &config.Config{
		CommonConfig: config.CommonConfig{
			Labels: []string{"foo:bar"},
		},
	}

	valuesSets := make(map[string]interface{})
	valuesSets["labels"] = "foo:baz"
	newConfig := &config.Config{
		CommonConfig: config.CommonConfig{
			Labels:    []string{"foo:baz"},
			ValuesSet: valuesSets,
		},
	}

	if err := daemon.Reload(newConfig); err != nil {
		t.Fatal(err)
	}

	label := daemon.configStore.Labels[0]
	if label != "foo:baz" {
		t.Fatalf("Expected daemon label `foo:baz`, got %s", label)
	}
}

func TestDaemonReloadAllowNondistributableArtifacts(t *testing.T) {
	daemon := &Daemon{
		configStore: &config.Config{},
	}

	var err error
	// Initialize daemon with some registries.
	daemon.RegistryService, err = registry.NewService(registry.ServiceOptions{
		AllowNondistributableArtifacts: []string{
			"127.0.0.0/8",
			"10.10.1.11:5000",
			"10.10.1.22:5000", // This will be removed during reload.
			"docker1.com",
			"docker2.com", // This will be removed during reload.
		},
	})
	if err != nil {
		t.Fatal(err)
	}

	registries := []string{
		"127.0.0.0/8",
		"10.10.1.11:5000",
		"10.10.1.33:5000", // This will be added during reload.
		"docker1.com",
		"docker3.com", // This will be added during reload.
	}

	newConfig := &config.Config{
		CommonConfig: config.CommonConfig{
			ServiceOptions: registry.ServiceOptions{
				AllowNondistributableArtifacts: registries,
			},
			ValuesSet: map[string]interface{}{
				"allow-nondistributable-artifacts": registries,
			},
		},
	}

	if err := daemon.Reload(newConfig); err != nil {
		t.Fatal(err)
	}

	actual := []string{}
	serviceConfig := daemon.RegistryService.ServiceConfig()
	for _, value := range serviceConfig.AllowNondistributableArtifactsCIDRs {
		actual = append(actual, value.String())
	}
	actual = append(actual, serviceConfig.AllowNondistributableArtifactsHostnames...)

	sort.Strings(registries)
	sort.Strings(actual)
	assert.Equal(t, registries, actual)
}

func TestDaemonReloadMirrors(t *testing.T) {
	daemon := &Daemon{}
	var err error
	daemon.RegistryService, err = registry.NewService(registry.ServiceOptions{
		InsecureRegistries: []string{},
		Mirrors: []string{
			"https://mirror.test1.com",
			"https://mirror.test2.com", // this will be removed when reloading
			"https://mirror.test3.com", // this will be removed when reloading
		},
	})
	if err != nil {
		t.Fatal(err)
	}

	daemon.configStore = &config.Config{}

	type pair struct {
		valid   bool
		mirrors []string
		after   []string
	}

	loadMirrors := []pair{
		{
			valid:   false,
			mirrors: []string{"10.10.1.11:5000"}, // this mirror is invalid
			after:   []string{},
		},
		{
			valid:   false,
			mirrors: []string{"mirror.test1.com"}, // this mirror is invalid
			after:   []string{},
		},
		{
			valid:   false,
			mirrors: []string{"10.10.1.11:5000", "mirror.test1.com"}, // mirrors are invalid
			after:   []string{},
		},
		{
			valid:   true,
			mirrors: []string{"https://mirror.test1.com", "https://mirror.test4.com"},
			after:   []string{"https://mirror.test1.com/", "https://mirror.test4.com/"},
		},
	}

	for _, value := range loadMirrors {
		valuesSets := make(map[string]interface{})
		valuesSets["registry-mirrors"] = value.mirrors

		newConfig := &config.Config{
			CommonConfig: config.CommonConfig{
				ServiceOptions: registry.ServiceOptions{
					Mirrors: value.mirrors,
				},
				ValuesSet: valuesSets,
			},
		}

		err := daemon.Reload(newConfig)
		if !value.valid && err == nil {
			// mirrors should be invalid, should be a non-nil error
			t.Fatalf("Expected daemon reload error with invalid mirrors: %s, while get nil", value.mirrors)
		}

		if value.valid {
			if err != nil {
				// mirrors should be valid, should be no error
				t.Fatal(err)
			}
			registryService := daemon.RegistryService.ServiceConfig()

			if len(registryService.Mirrors) != len(value.after) {
				t.Fatalf("Expected %d daemon mirrors %s while get %d with %s",
					len(value.after),
					value.after,
					len(registryService.Mirrors),
					registryService.Mirrors)
			}

			dataMap := map[string]struct{}{}

			for _, mirror := range registryService.Mirrors {
				if _, exist := dataMap[mirror]; !exist {
					dataMap[mirror] = struct{}{}
				}
			}

			for _, address := range value.after {
				if _, exist := dataMap[address]; !exist {
					t.Fatalf("Expected %s in daemon mirrors, while get none", address)
				}
			}
		}
	}
}

func TestDaemonReloadInsecureRegistries(t *testing.T) {
	daemon := &Daemon{}
	var err error
	// initialize daemon with existing insecure registries: "127.0.0.0/8", "10.10.1.11:5000", "10.10.1.22:5000"
	daemon.RegistryService, err = registry.NewService(registry.ServiceOptions{
		InsecureRegistries: []string{
			"127.0.0.0/8",
			"10.10.1.11:5000",
			"10.10.1.22:5000", // this will be removed when reloading
			"docker1.com",
			"docker2.com", // this will be removed when reloading
		},
	})
	if err != nil {
		t.Fatal(err)
	}

	daemon.configStore = &config.Config{}

	insecureRegistries := []string{
		"127.0.0.0/8",     // this will be kept
		"10.10.1.11:5000", // this will be kept
		"10.10.1.33:5000", // this will be newly added
		"docker1.com",     // this will be kept
		"docker3.com",     // this will be newly added
	}

	valuesSets := make(map[string]interface{})
	valuesSets["insecure-registries"] = insecureRegistries

	newConfig := &config.Config{
		CommonConfig: config.CommonConfig{
			ServiceOptions: registry.ServiceOptions{
				InsecureRegistries: insecureRegistries,
			},
			ValuesSet: valuesSets,
		},
	}

	if err := daemon.Reload(newConfig); err != nil {
		t.Fatal(err)
	}

	// After Reload, daemon.RegistryService will be changed which is useful
	// for registry communication in daemon.
	registries := daemon.RegistryService.ServiceConfig()

	// After Reload(), newConfig has come to registries.InsecureRegistryCIDRs and registries.IndexConfigs in daemon.
	// Then collect registries.InsecureRegistryCIDRs in dataMap.
	// When collecting, we need to convert CIDRS into string as a key,
	// while the times of key appears as value.
	dataMap := map[string]int{}
	for _, value := range registries.InsecureRegistryCIDRs {
		if _, ok := dataMap[value.String()]; !ok {
			dataMap[value.String()] = 1
		} else {
			dataMap[value.String()]++
		}
	}

	for _, value := range registries.IndexConfigs {
		if _, ok := dataMap[value.Name]; !ok {
			dataMap[value.Name] = 1
		} else {
			dataMap[value.Name]++
		}
	}

	// Finally compare dataMap with the original insecureRegistries.
	// Each value in insecureRegistries should appear in daemon's insecure registries,
	// and each can only appear exactly ONCE.
	for _, r := range insecureRegistries {
		if value, ok := dataMap[r]; !ok {
			t.Fatalf("Expected daemon insecure registry %s, got none", r)
		} else if value != 1 {
			t.Fatalf("Expected only 1 daemon insecure registry %s, got %d", r, value)
		}
	}

	// assert if "10.10.1.22:5000" is removed when reloading
	if value, ok := dataMap["10.10.1.22:5000"]; ok {
		t.Fatalf("Expected no insecure registry of 10.10.1.22:5000, got %d", value)
	}

	// assert if "docker2.com" is removed when reloading
	if value, ok := dataMap["docker2.com"]; ok {
		t.Fatalf("Expected no insecure registry of docker2.com, got %d", value)
	}
}

func TestDaemonReloadNotAffectOthers(t *testing.T) {
	daemon := &Daemon{}
	daemon.configStore = &config.Config{
		CommonConfig: config.CommonConfig{
			Labels: []string{"foo:bar"},
			Debug:  true,
		},
	}

	valuesSets := make(map[string]interface{})
	valuesSets["labels"] = "foo:baz"
	newConfig := &config.Config{
		CommonConfig: config.CommonConfig{
			Labels:    []string{"foo:baz"},
			ValuesSet: valuesSets,
		},
	}

	if err := daemon.Reload(newConfig); err != nil {
		t.Fatal(err)
	}

	label := daemon.configStore.Labels[0]
	if label != "foo:baz" {
		t.Fatalf("Expected daemon label `foo:baz`, got %s", label)
	}
	debug := daemon.configStore.Debug
	if !debug {
		t.Fatal("Expected debug 'enabled', got 'disabled'")
	}
}

func TestDaemonDiscoveryReload(t *testing.T) {
	daemon := &Daemon{}
	daemon.configStore = &config.Config{
		CommonConfig: config.CommonConfig{
			ClusterStore:     "memory://127.0.0.1",
			ClusterAdvertise: "127.0.0.1:3333",
		},
	}

	if err := daemon.initDiscovery(daemon.configStore); err != nil {
		t.Fatal(err)
	}

	expected := discovery.Entries{
		&discovery.Entry{Host: "127.0.0.1", Port: "3333"},
	}

	select {
	case <-time.After(10 * time.Second):
		t.Fatal("timeout waiting for discovery")
	case <-daemon.discoveryWatcher.ReadyCh():
	}

	stopCh := make(chan struct{})
	defer close(stopCh)
	ch, errCh := daemon.discoveryWatcher.Watch(stopCh)

	select {
	case <-time.After(1 * time.Second):
		t.Fatal("failed to get discovery advertisements in time")
	case e := <-ch:
		if !reflect.DeepEqual(e, expected) {
			t.Fatalf("expected %v, got %v\n", expected, e)
		}
	case e := <-errCh:
		t.Fatal(e)
	}

	valuesSets := make(map[string]interface{})
	valuesSets["cluster-store"] = "memory://127.0.0.1:2222"
	valuesSets["cluster-advertise"] = "127.0.0.1:5555"
	newConfig := &config.Config{
		CommonConfig: config.CommonConfig{
			ClusterStore:     "memory://127.0.0.1:2222",
			ClusterAdvertise: "127.0.0.1:5555",
			ValuesSet:        valuesSets,
		},
	}

	expected = discovery.Entries{
		&discovery.Entry{Host: "127.0.0.1", Port: "5555"},
	}

	if err := daemon.Reload(newConfig); err != nil {
		t.Fatal(err)
	}

	select {
	case <-time.After(10 * time.Second):
		t.Fatal("timeout waiting for discovery")
	case <-daemon.discoveryWatcher.ReadyCh():
	}

	ch, errCh = daemon.discoveryWatcher.Watch(stopCh)

	select {
	case <-time.After(1 * time.Second):
		t.Fatal("failed to get discovery advertisements in time")
	case e := <-ch:
		if !reflect.DeepEqual(e, expected) {
			t.Fatalf("expected %v, got %v\n", expected, e)
		}
	case e := <-errCh:
		t.Fatal(e)
	}
}

func TestDaemonDiscoveryReloadFromEmptyDiscovery(t *testing.T) {
	daemon := &Daemon{}
	daemon.configStore = &config.Config{}

	valuesSet := make(map[string]interface{})
	valuesSet["cluster-store"] = "memory://127.0.0.1:2222"
	valuesSet["cluster-advertise"] = "127.0.0.1:5555"
	newConfig := &config.Config{
		CommonConfig: config.CommonConfig{
			ClusterStore:     "memory://127.0.0.1:2222",
			ClusterAdvertise: "127.0.0.1:5555",
			ValuesSet:        valuesSet,
		},
	}

	expected := discovery.Entries{
		&discovery.Entry{Host: "127.0.0.1", Port: "5555"},
	}

	if err := daemon.Reload(newConfig); err != nil {
		t.Fatal(err)
	}

	select {
	case <-time.After(10 * time.Second):
		t.Fatal("timeout waiting for discovery")
	case <-daemon.discoveryWatcher.ReadyCh():
	}

	stopCh := make(chan struct{})
	defer close(stopCh)
	ch, errCh := daemon.discoveryWatcher.Watch(stopCh)

	select {
	case <-time.After(1 * time.Second):
		t.Fatal("failed to get discovery advertisements in time")
	case e := <-ch:
		if !reflect.DeepEqual(e, expected) {
			t.Fatalf("expected %v, got %v\n", expected, e)
		}
	case e := <-errCh:
		t.Fatal(e)
	}
}

func TestDaemonDiscoveryReloadOnlyClusterAdvertise(t *testing.T) {
	daemon := &Daemon{}
	daemon.configStore = &config.Config{
		CommonConfig: config.CommonConfig{
			ClusterStore: "memory://127.0.0.1",
		},
	}
	valuesSets := make(map[string]interface{})
	valuesSets["cluster-advertise"] = "127.0.0.1:5555"
	newConfig := &config.Config{
		CommonConfig: config.CommonConfig{
			ClusterAdvertise: "127.0.0.1:5555",
			ValuesSet:        valuesSets,
		},
	}
	expected := discovery.Entries{
		&discovery.Entry{Host: "127.0.0.1", Port: "5555"},
	}

	if err := daemon.Reload(newConfig); err != nil {
		t.Fatal(err)
	}

	select {
	case <-daemon.discoveryWatcher.ReadyCh():
	case <-time.After(10 * time.Second):
		t.Fatal("Timeout waiting for discovery")
	}
	stopCh := make(chan struct{})
	defer close(stopCh)
	ch, errCh := daemon.discoveryWatcher.Watch(stopCh)

	select {
	case <-time.After(1 * time.Second):
		t.Fatal("failed to get discovery advertisements in time")
	case e := <-ch:
		if !reflect.DeepEqual(e, expected) {
			t.Fatalf("expected %v, got %v\n", expected, e)
		}
	case e := <-errCh:
		t.Fatal(e)
	}
}
