package daemon // import "github.com/docker/docker/daemon"

import (
	"os"
	"sort"
	"testing"

	"github.com/containerd/log"
	"github.com/docker/docker/daemon/config"
	"github.com/docker/docker/daemon/images"
	"github.com/docker/docker/libnetwork"
	"github.com/docker/docker/registry"
	"gotest.tools/v3/assert"
	is "gotest.tools/v3/assert/cmp"
)

// muteLogs suppresses logs that are generated during the test
func muteLogs(t *testing.T) {
	t.Helper()
	err := log.SetLevel("error")
	if err != nil {
		t.Error(err)
	}
}

func newDaemonForReloadT(t *testing.T, cfg *config.Config) *Daemon {
	t.Helper()
	daemon := &Daemon{
		imageService: images.NewImageService(images.ImageServiceConfig{}),
	}
	var err error
	daemon.registryService, err = registry.NewService(registry.ServiceOptions{})
	assert.Assert(t, err)
	daemon.configStore.Store(&configStore{Config: *cfg})
	return daemon
}

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

	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.config().Labels[0]
	if label != "foo:baz" {
		t.Fatalf("Expected daemon label `foo:baz`, got %s", label)
	}
}

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

	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)
	}

	var 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.Check(t, is.DeepEqual(registries, actual))
}

func TestDaemonReloadMirrors(t *testing.T) {
	daemon := &Daemon{
		imageService: images.NewImageService(images.ImageServiceConfig{}),
	}
	muteLogs(t)

	var err error
	daemon.registryService, err = registry.NewService(registry.ServiceOptions{
		InsecureRegistries: []string{},
		Mirrors: []string{
			"https://mirror.test1.example.com",
			"https://mirror.test2.example.com", // this will be removed when reloading
			"https://mirror.test3.example.com", // this will be removed when reloading
		},
	})
	if err != nil {
		t.Fatal(err)
	}

	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.example.com"}, // mirrors are invalid
			after:   []string{},
		},
		{
			valid:   true,
			mirrors: []string{"https://mirror.test1.example.com", "https://mirror.test4.example.com"},
			after:   []string{"https://mirror.test1.example.com/", "https://mirror.test4.example.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{
		imageService: images.NewImageService(images.ImageServiceConfig{}),
	}
	muteLogs(t)

	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.example.com",
			"docker2.example.com", // this will be removed when reloading
		},
	})
	if err != nil {
		t.Fatal(err)
	}

	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.example.com", // this will be kept
		"docker3.example.com", // this will be newly added
	}

	mirrors := []string{
		"https://mirror.test.example.com",
	}

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

	newConfig := &config.Config{
		CommonConfig: config.CommonConfig{
			ServiceOptions: registry.ServiceOptions{
				InsecureRegistries: insecureRegistries,
				Mirrors:            mirrors,
			},
			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.example.com"]; ok {
		t.Fatalf("Expected no insecure registry of docker2.com, got %d", value)
	}
}

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

	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.config().Labels[0]
	if label != "foo:baz" {
		t.Fatalf("Expected daemon label `foo:baz`, got %s", label)
	}
	debug := daemon.config().Debug
	if !debug {
		t.Fatal("Expected debug 'enabled', got 'disabled'")
	}
}

func TestDaemonReloadNetworkDiagnosticPort(t *testing.T) {
	if os.Getuid() != 0 {
		t.Skip("root required")
	}
	daemon := newDaemonForReloadT(t, &config.Config{})

	enableConfig := &config.Config{
		CommonConfig: config.CommonConfig{
			NetworkDiagnosticPort: 2000,
			ValuesSet: map[string]interface{}{
				"network-diagnostic-port": 2000,
			},
		},
	}

	netOptions, err := daemon.networkOptions(&config.Config{CommonConfig: config.CommonConfig{Root: t.TempDir()}}, nil, "", nil)
	if err != nil {
		t.Fatal(err)
	}
	controller, err := libnetwork.New(netOptions...)
	if err != nil {
		t.Fatal(err)
	}
	daemon.netController = controller

	// Enable/Disable the server for some iterations
	for i := 0; i < 10; i++ {
		enableConfig.CommonConfig.NetworkDiagnosticPort++
		if err := daemon.Reload(enableConfig); err != nil {
			t.Fatal(err)
		}
		// Check that the diagnostic is enabled
		if !daemon.netController.IsDiagnosticEnabled() {
			t.Fatalf("diagnostic should be enabled")
		}

		// Reload
		if err := daemon.Reload(&config.Config{}); err != nil {
			t.Fatal(err)
		}
		// Check that the diagnostic is disabled
		if daemon.netController.IsDiagnosticEnabled() {
			t.Fatalf("diagnostic should be disabled")
		}
	}

	enableConfig.CommonConfig.NetworkDiagnosticPort++
	// 2 times the enable should not create problems
	if err := daemon.Reload(enableConfig); err != nil {
		t.Fatal(err)
	}
	// Check that the diagnostic is enabled
	if !daemon.netController.IsDiagnosticEnabled() {
		t.Fatalf("diagnostic should be enable")
	}

	// Check that another reload does not cause issues
	if err := daemon.Reload(enableConfig); err != nil {
		t.Fatal(err)
	}
	// Check that the diagnostic is enable
	if !daemon.netController.IsDiagnosticEnabled() {
		t.Fatalf("diagnostic should be enable")
	}
}
