package service // import "github.com/docker/docker/integration/service"

import (
	"context"
	"testing"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/filters"
	swarmtypes "github.com/docker/docker/api/types/swarm"
	"github.com/docker/docker/api/types/versions"
	"github.com/docker/docker/client"
	"github.com/docker/docker/integration/internal/network"
	"github.com/docker/docker/integration/internal/swarm"
	"gotest.tools/v3/assert"
	is "gotest.tools/v3/assert/cmp"
	"gotest.tools/v3/poll"
	"gotest.tools/v3/skip"
)

func TestServiceUpdateLabel(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
	defer setupTest(t)()
	d := swarm.NewSwarm(t, testEnv)
	defer d.Stop(t)
	cli := d.NewClientT(t)
	defer cli.Close()

	ctx := context.Background()
	serviceName := "TestService_" + t.Name()
	serviceID := swarm.CreateService(t, d, swarm.ServiceWithName(serviceName))
	service := getService(t, cli, serviceID)
	assert.Check(t, is.DeepEqual(service.Spec.Labels, map[string]string{}))

	// add label to empty set
	service.Spec.Labels["foo"] = "bar"
	_, err := cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceSpecIsUpdated(cli, serviceID, service.Version.Index), swarm.ServicePoll)
	service = getService(t, cli, serviceID)
	assert.Check(t, is.DeepEqual(service.Spec.Labels, map[string]string{"foo": "bar"}))

	// add label to non-empty set
	service.Spec.Labels["foo2"] = "bar"
	_, err = cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceSpecIsUpdated(cli, serviceID, service.Version.Index), swarm.ServicePoll)
	service = getService(t, cli, serviceID)
	assert.Check(t, is.DeepEqual(service.Spec.Labels, map[string]string{"foo": "bar", "foo2": "bar"}))

	delete(service.Spec.Labels, "foo2")
	_, err = cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceSpecIsUpdated(cli, serviceID, service.Version.Index), swarm.ServicePoll)
	service = getService(t, cli, serviceID)
	assert.Check(t, is.DeepEqual(service.Spec.Labels, map[string]string{"foo": "bar"}))

	delete(service.Spec.Labels, "foo")
	_, err = cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceSpecIsUpdated(cli, serviceID, service.Version.Index), swarm.ServicePoll)
	service = getService(t, cli, serviceID)
	assert.Check(t, is.DeepEqual(service.Spec.Labels, map[string]string{}))

	// now make sure we can add again
	service.Spec.Labels["foo"] = "bar"
	_, err = cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceSpecIsUpdated(cli, serviceID, service.Version.Index), swarm.ServicePoll)
	service = getService(t, cli, serviceID)
	assert.Check(t, is.DeepEqual(service.Spec.Labels, map[string]string{"foo": "bar"}))

	err = cli.ServiceRemove(context.Background(), serviceID)
	assert.NilError(t, err)
}

func TestServiceUpdateSecrets(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
	defer setupTest(t)()
	d := swarm.NewSwarm(t, testEnv)
	defer d.Stop(t)
	cli := d.NewClientT(t)
	defer cli.Close()

	ctx := context.Background()
	secretName := "TestSecret_" + t.Name()
	secretTarget := "targetName"
	resp, err := cli.SecretCreate(ctx, swarmtypes.SecretSpec{
		Annotations: swarmtypes.Annotations{
			Name: secretName,
		},
		Data: []byte("TESTINGDATA"),
	})
	assert.NilError(t, err)
	assert.Check(t, resp.ID != "")

	serviceName := "TestService_" + t.Name()
	serviceID := swarm.CreateService(t, d, swarm.ServiceWithName(serviceName))
	service := getService(t, cli, serviceID)

	// add secret
	service.Spec.TaskTemplate.ContainerSpec.Secrets = append(service.Spec.TaskTemplate.ContainerSpec.Secrets,
		&swarmtypes.SecretReference{
			File: &swarmtypes.SecretReferenceFileTarget{
				Name: secretTarget,
				UID:  "0",
				GID:  "0",
				Mode: 0600,
			},
			SecretID:   resp.ID,
			SecretName: secretName,
		},
	)
	_, err = cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceIsUpdated(cli, serviceID), swarm.ServicePoll)

	service = getService(t, cli, serviceID)
	secrets := service.Spec.TaskTemplate.ContainerSpec.Secrets
	assert.Assert(t, is.Equal(1, len(secrets)))

	secret := *secrets[0]
	assert.Check(t, is.Equal(secretName, secret.SecretName))
	assert.Check(t, nil != secret.File)
	assert.Check(t, is.Equal(secretTarget, secret.File.Name))

	// remove
	service.Spec.TaskTemplate.ContainerSpec.Secrets = []*swarmtypes.SecretReference{}
	_, err = cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceIsUpdated(cli, serviceID), swarm.ServicePoll)
	service = getService(t, cli, serviceID)
	assert.Check(t, is.Equal(0, len(service.Spec.TaskTemplate.ContainerSpec.Secrets)))

	err = cli.ServiceRemove(context.Background(), serviceID)
	assert.NilError(t, err)
}

func TestServiceUpdateConfigs(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
	defer setupTest(t)()
	d := swarm.NewSwarm(t, testEnv)
	defer d.Stop(t)
	cli := d.NewClientT(t)
	defer cli.Close()

	ctx := context.Background()
	configName := "TestConfig_" + t.Name()
	configTarget := "targetName"
	resp, err := cli.ConfigCreate(ctx, swarmtypes.ConfigSpec{
		Annotations: swarmtypes.Annotations{
			Name: configName,
		},
		Data: []byte("TESTINGDATA"),
	})
	assert.NilError(t, err)
	assert.Check(t, resp.ID != "")

	serviceName := "TestService_" + t.Name()
	serviceID := swarm.CreateService(t, d, swarm.ServiceWithName(serviceName))
	service := getService(t, cli, serviceID)

	// add config
	service.Spec.TaskTemplate.ContainerSpec.Configs = append(service.Spec.TaskTemplate.ContainerSpec.Configs,
		&swarmtypes.ConfigReference{
			File: &swarmtypes.ConfigReferenceFileTarget{
				Name: configTarget,
				UID:  "0",
				GID:  "0",
				Mode: 0600,
			},
			ConfigID:   resp.ID,
			ConfigName: configName,
		},
	)
	_, err = cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceIsUpdated(cli, serviceID), swarm.ServicePoll)

	service = getService(t, cli, serviceID)
	configs := service.Spec.TaskTemplate.ContainerSpec.Configs
	assert.Assert(t, is.Equal(1, len(configs)))

	config := *configs[0]
	assert.Check(t, is.Equal(configName, config.ConfigName))
	assert.Check(t, nil != config.File)
	assert.Check(t, is.Equal(configTarget, config.File.Name))

	// remove
	service.Spec.TaskTemplate.ContainerSpec.Configs = []*swarmtypes.ConfigReference{}
	_, err = cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceIsUpdated(cli, serviceID), swarm.ServicePoll)
	service = getService(t, cli, serviceID)
	assert.Check(t, is.Equal(0, len(service.Spec.TaskTemplate.ContainerSpec.Configs)))

	err = cli.ServiceRemove(context.Background(), serviceID)
	assert.NilError(t, err)
}

func TestServiceUpdateNetwork(t *testing.T) {
	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
	defer setupTest(t)()
	d := swarm.NewSwarm(t, testEnv)
	defer d.Stop(t)
	cli := d.NewClientT(t)
	defer cli.Close()

	ctx := context.Background()

	// Create a overlay network
	testNet := "testNet" + t.Name()
	overlayID := network.CreateNoError(ctx, t, cli, testNet,
		network.WithDriver("overlay"))

	var instances uint64 = 1
	// Create service with the overlay network
	serviceName := "TestServiceUpdateNetworkRM_" + t.Name()
	serviceID := swarm.CreateService(t, d,
		swarm.ServiceWithReplicas(instances),
		swarm.ServiceWithName(serviceName),
		swarm.ServiceWithNetwork(testNet))

	poll.WaitOn(t, swarm.RunningTasksCount(cli, serviceID, instances), swarm.ServicePoll)
	service := getService(t, cli, serviceID)
	netInfo, err := cli.NetworkInspect(ctx, testNet, types.NetworkInspectOptions{
		Verbose: true,
		Scope:   "swarm",
	})
	assert.NilError(t, err)
	assert.Assert(t, len(netInfo.Containers) == 2, "Expected 2 endpoints, one for container and one for LB Sandbox")

	// Remove network from service
	service.Spec.TaskTemplate.Networks = []swarmtypes.NetworkAttachmentConfig{}
	_, err = cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	assert.NilError(t, err)
	poll.WaitOn(t, serviceIsUpdated(cli, serviceID), swarm.ServicePoll)

	netInfo, err = cli.NetworkInspect(ctx, testNet, types.NetworkInspectOptions{
		Verbose: true,
		Scope:   "swarm",
	})

	assert.NilError(t, err)
	assert.Assert(t, len(netInfo.Containers) == 0, "Load balancing endpoint still exists in network")

	err = cli.NetworkRemove(ctx, overlayID)
	assert.NilError(t, err)

	err = cli.ServiceRemove(ctx, serviceID)
	assert.NilError(t, err)
}

// TestServiceUpdatePidsLimit tests creating and updating a service with PidsLimit
func TestServiceUpdatePidsLimit(t *testing.T) {
	skip.If(
		t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.41"),
		"setting pidslimit for services is not supported before api v1.41",
	)
	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
	tests := []struct {
		name      string
		pidsLimit int64
		expected  int64
	}{
		{
			name:      "create service with PidsLimit 300",
			pidsLimit: 300,
			expected:  300,
		},
		{
			name:      "unset PidsLimit to 0",
			pidsLimit: 0,
			expected:  0,
		},
		{
			name:      "update PidsLimit to 100",
			pidsLimit: 100,
			expected:  100,
		},
	}

	defer setupTest(t)()
	d := swarm.NewSwarm(t, testEnv)
	defer d.Stop(t)
	cli := d.NewClientT(t)
	defer func() { _ = cli.Close() }()
	ctx := context.Background()
	var (
		serviceID string
		service   swarmtypes.Service
	)
	for i, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			if i == 0 {
				serviceID = swarm.CreateService(t, d, swarm.ServiceWithPidsLimit(tc.pidsLimit))
			} else {
				service = getService(t, cli, serviceID)
				if service.Spec.TaskTemplate.Resources == nil {
					service.Spec.TaskTemplate.Resources = &swarmtypes.ResourceRequirements{}
				}
				if service.Spec.TaskTemplate.Resources.Limits == nil {
					service.Spec.TaskTemplate.Resources.Limits = &swarmtypes.Limit{}
				}
				service.Spec.TaskTemplate.Resources.Limits.Pids = tc.pidsLimit
				_, err := cli.ServiceUpdate(ctx, serviceID, service.Version, service.Spec, types.ServiceUpdateOptions{})
				assert.NilError(t, err)
				poll.WaitOn(t, serviceIsUpdated(cli, serviceID), swarm.ServicePoll)
			}

			poll.WaitOn(t, swarm.RunningTasksCount(cli, serviceID, 1), swarm.ServicePoll)
			service = getService(t, cli, serviceID)
			container := getServiceTaskContainer(ctx, t, cli, serviceID)
			assert.Equal(t, service.Spec.TaskTemplate.Resources.Limits.Pids, tc.expected)
			if tc.expected == 0 {
				if container.HostConfig.Resources.PidsLimit != nil {
					t.Fatalf("Expected container.HostConfig.Resources.PidsLimit to be nil")
				}
			} else {
				assert.Assert(t, container.HostConfig.Resources.PidsLimit != nil)
				assert.Equal(t, *container.HostConfig.Resources.PidsLimit, tc.expected)
			}
		})
	}

	err := cli.ServiceRemove(ctx, serviceID)
	assert.NilError(t, err)
}

func getServiceTaskContainer(ctx context.Context, t *testing.T, cli client.APIClient, serviceID string) types.ContainerJSON {
	t.Helper()
	filter := filters.NewArgs()
	filter.Add("service", serviceID)
	filter.Add("desired-state", "running")
	tasks, err := cli.TaskList(ctx, types.TaskListOptions{Filters: filter})
	assert.NilError(t, err)
	assert.Assert(t, len(tasks) > 0)

	ctr, err := cli.ContainerInspect(ctx, tasks[0].Status.ContainerStatus.ContainerID)
	assert.NilError(t, err)
	assert.Equal(t, ctr.State.Running, true)
	return ctr
}

func getService(t *testing.T, cli client.ServiceAPIClient, serviceID string) swarmtypes.Service {
	t.Helper()
	service, _, err := cli.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
	assert.NilError(t, err)
	return service
}

func serviceIsUpdated(client client.ServiceAPIClient, serviceID string) func(log poll.LogT) poll.Result {
	return func(log poll.LogT) poll.Result {
		service, _, err := client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
		switch {
		case err != nil:
			return poll.Error(err)
		case service.UpdateStatus != nil && service.UpdateStatus.State == swarmtypes.UpdateStateCompleted:
			return poll.Success()
		default:
			if service.UpdateStatus != nil {
				return poll.Continue("waiting for service %s to be updated, state: %s, message: %s", serviceID, service.UpdateStatus.State, service.UpdateStatus.Message)
			}
			return poll.Continue("waiting for service %s to be updated", serviceID)
		}
	}
}

func serviceSpecIsUpdated(client client.ServiceAPIClient, serviceID string, serviceOldVersion uint64) func(log poll.LogT) poll.Result {
	return func(log poll.LogT) poll.Result {
		service, _, err := client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
		switch {
		case err != nil:
			return poll.Error(err)
		case service.Version.Index > serviceOldVersion:
			return poll.Success()
		default:
			return poll.Continue("waiting for service %s to be updated", serviceID)
		}
	}
}
