package main

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"strings"
	"testing"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/filters"
	"github.com/docker/docker/api/types/network"
	"github.com/docker/docker/api/types/versions"
	"github.com/docker/docker/testutil/request"
	"gotest.tools/v3/assert"
)

func (s *DockerAPISuite) TestAPINetworkGetDefaults(c *testing.T) {
	testRequires(c, DaemonIsLinux)
	// By default docker daemon creates 3 networks. check if they are present
	defaults := []string{"bridge", "host", "none"}
	for _, nn := range defaults {
		assert.Assert(c, isNetworkAvailable(c, nn))
	}
}

func (s *DockerAPISuite) TestAPINetworkCreateCheckDuplicate(c *testing.T) {
	testRequires(c, DaemonIsLinux)
	name := "testcheckduplicate"
	configOnCheck := types.NetworkCreateRequest{
		Name: name,
		NetworkCreate: types.NetworkCreate{
			CheckDuplicate: true,
		},
	}
	configNotCheck := types.NetworkCreateRequest{
		Name: name,
		NetworkCreate: types.NetworkCreate{
			CheckDuplicate: false,
		},
	}

	// Creating a new network first
	createNetwork(c, configOnCheck, http.StatusCreated)
	assert.Assert(c, isNetworkAvailable(c, name))

	// Creating another network with same name and CheckDuplicate must fail
	isOlderAPI := versions.LessThan(testEnv.DaemonAPIVersion(), "1.34")
	expectedStatus := http.StatusConflict
	if isOlderAPI {
		// In the early test code it uses bool value to represent
		// whether createNetwork() is expected to fail or not.
		// Therefore, we use negation to handle the same logic after
		// the code was changed in https://github.com/moby/moby/pull/35030
		// -http.StatusCreated will also be checked as NOT equal to
		// http.StatusCreated in createNetwork() function.
		expectedStatus = -http.StatusCreated
	}
	createNetwork(c, configOnCheck, expectedStatus)

	// Creating another network with same name and not CheckDuplicate must succeed
	createNetwork(c, configNotCheck, http.StatusCreated)
}

func (s *DockerAPISuite) TestAPINetworkFilter(c *testing.T) {
	testRequires(c, DaemonIsLinux)
	nr := getNetworkResource(c, getNetworkIDByName(c, "bridge"))
	assert.Equal(c, nr.Name, "bridge")
}

func (s *DockerAPISuite) TestAPINetworkInspectBridge(c *testing.T) {
	testRequires(c, DaemonIsLinux)
	// Inspect default bridge network
	nr := getNetworkResource(c, "bridge")
	assert.Equal(c, nr.Name, "bridge")

	// run a container and attach it to the default bridge network
	out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
	containerID := strings.TrimSpace(out)
	containerIP := findContainerIP(c, "test", "bridge")

	// inspect default bridge network again and make sure the container is connected
	nr = getNetworkResource(c, nr.ID)
	assert.Equal(c, nr.Driver, "bridge")
	assert.Equal(c, nr.Scope, "local")
	assert.Equal(c, nr.Internal, false)
	assert.Equal(c, nr.EnableIPv6, false)
	assert.Equal(c, nr.IPAM.Driver, "default")
	_, ok := nr.Containers[containerID]
	assert.Assert(c, ok)

	ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
	assert.NilError(c, err)
	assert.Equal(c, ip.String(), containerIP)
}

func (s *DockerAPISuite) TestAPINetworkInspectUserDefinedNetwork(c *testing.T) {
	testRequires(c, DaemonIsLinux)
	// IPAM configuration inspect
	ipam := &network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "172.28.0.0/16", IPRange: "172.28.5.0/24", Gateway: "172.28.5.254"}},
	}
	config := types.NetworkCreateRequest{
		Name: "br0",
		NetworkCreate: types.NetworkCreate{
			Driver:  "bridge",
			IPAM:    ipam,
			Options: map[string]string{"foo": "bar", "opts": "dopts"},
		},
	}
	id0 := createNetwork(c, config, http.StatusCreated)
	assert.Assert(c, isNetworkAvailable(c, "br0"))

	nr := getNetworkResource(c, id0)
	assert.Equal(c, len(nr.IPAM.Config), 1)
	assert.Equal(c, nr.IPAM.Config[0].Subnet, "172.28.0.0/16")
	assert.Equal(c, nr.IPAM.Config[0].IPRange, "172.28.5.0/24")
	assert.Equal(c, nr.IPAM.Config[0].Gateway, "172.28.5.254")
	assert.Equal(c, nr.Options["foo"], "bar")
	assert.Equal(c, nr.Options["opts"], "dopts")

	// delete the network and make sure it is deleted
	deleteNetwork(c, id0, true)
	assert.Assert(c, !isNetworkAvailable(c, "br0"))
}

func (s *DockerAPISuite) TestAPINetworkConnectDisconnect(c *testing.T) {
	testRequires(c, DaemonIsLinux)
	// Create test network
	name := "testnetwork"
	config := types.NetworkCreateRequest{
		Name: name,
	}
	id := createNetwork(c, config, http.StatusCreated)
	nr := getNetworkResource(c, id)
	assert.Equal(c, nr.Name, name)
	assert.Equal(c, nr.ID, id)
	assert.Equal(c, len(nr.Containers), 0)

	// run a container
	out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
	containerID := strings.TrimSpace(out)

	// connect the container to the test network
	connectNetwork(c, nr.ID, containerID)

	// inspect the network to make sure container is connected
	nr = getNetworkResource(c, nr.ID)
	assert.Equal(c, len(nr.Containers), 1)
	_, ok := nr.Containers[containerID]
	assert.Assert(c, ok)

	// check if container IP matches network inspect
	ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
	assert.NilError(c, err)
	containerIP := findContainerIP(c, "test", "testnetwork")
	assert.Equal(c, ip.String(), containerIP)

	// disconnect container from the network
	disconnectNetwork(c, nr.ID, containerID)
	nr = getNetworkResource(c, nr.ID)
	assert.Equal(c, nr.Name, name)
	assert.Equal(c, len(nr.Containers), 0)

	// delete the network
	deleteNetwork(c, nr.ID, true)
}

func (s *DockerAPISuite) TestAPINetworkIPAMMultipleBridgeNetworks(c *testing.T) {
	testRequires(c, DaemonIsLinux)
	// test0 bridge network
	ipam0 := &network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "192.178.0.0/16", IPRange: "192.178.128.0/17", Gateway: "192.178.138.100"}},
	}
	config0 := types.NetworkCreateRequest{
		Name: "test0",
		NetworkCreate: types.NetworkCreate{
			Driver: "bridge",
			IPAM:   ipam0,
		},
	}
	id0 := createNetwork(c, config0, http.StatusCreated)
	assert.Assert(c, isNetworkAvailable(c, "test0"))

	ipam1 := &network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "192.178.128.0/17", Gateway: "192.178.128.1"}},
	}
	// test1 bridge network overlaps with test0
	config1 := types.NetworkCreateRequest{
		Name: "test1",
		NetworkCreate: types.NetworkCreate{
			Driver: "bridge",
			IPAM:   ipam1,
		},
	}
	if versions.LessThan(testEnv.DaemonAPIVersion(), "1.32") {
		createNetwork(c, config1, http.StatusInternalServerError)
	} else {
		createNetwork(c, config1, http.StatusForbidden)
	}
	assert.Assert(c, !isNetworkAvailable(c, "test1"))

	ipam2 := &network.IPAM{
		Driver: "default",
		Config: []network.IPAMConfig{{Subnet: "192.169.0.0/16", Gateway: "192.169.100.100"}},
	}
	// test2 bridge network does not overlap
	config2 := types.NetworkCreateRequest{
		Name: "test2",
		NetworkCreate: types.NetworkCreate{
			Driver: "bridge",
			IPAM:   ipam2,
		},
	}
	createNetwork(c, config2, http.StatusCreated)
	assert.Assert(c, isNetworkAvailable(c, "test2"))

	// remove test0 and retry to create test1
	deleteNetwork(c, id0, true)
	createNetwork(c, config1, http.StatusCreated)
	assert.Assert(c, isNetworkAvailable(c, "test1"))

	// for networks w/o ipam specified, docker will choose proper non-overlapping subnets
	createNetwork(c, types.NetworkCreateRequest{Name: "test3"}, http.StatusCreated)
	assert.Assert(c, isNetworkAvailable(c, "test3"))
	createNetwork(c, types.NetworkCreateRequest{Name: "test4"}, http.StatusCreated)
	assert.Assert(c, isNetworkAvailable(c, "test4"))
	createNetwork(c, types.NetworkCreateRequest{Name: "test5"}, http.StatusCreated)
	assert.Assert(c, isNetworkAvailable(c, "test5"))

	for i := 1; i < 6; i++ {
		deleteNetwork(c, fmt.Sprintf("test%d", i), true)
	}
}

func (s *DockerAPISuite) TestAPICreateDeletePredefinedNetworks(c *testing.T) {
	testRequires(c, DaemonIsLinux, SwarmInactive)
	createDeletePredefinedNetwork(c, "bridge")
	createDeletePredefinedNetwork(c, "none")
	createDeletePredefinedNetwork(c, "host")
}

func createDeletePredefinedNetwork(c *testing.T, name string) {
	// Create pre-defined network
	config := types.NetworkCreateRequest{
		Name: name,
		NetworkCreate: types.NetworkCreate{
			CheckDuplicate: true,
		},
	}
	expectedStatus := http.StatusForbidden
	if versions.LessThan(testEnv.DaemonAPIVersion(), "1.34") {
		// In the early test code it uses bool value to represent
		// whether createNetwork() is expected to fail or not.
		// Therefore, we use negation to handle the same logic after
		// the code was changed in https://github.com/moby/moby/pull/35030
		// -http.StatusCreated will also be checked as NOT equal to
		// http.StatusCreated in createNetwork() function.
		expectedStatus = -http.StatusCreated
	}
	createNetwork(c, config, expectedStatus)
	deleteNetwork(c, name, false)
}

func isNetworkAvailable(c *testing.T, name string) bool {
	resp, body, err := request.Get("/networks")
	assert.NilError(c, err)
	defer resp.Body.Close()
	assert.Equal(c, resp.StatusCode, http.StatusOK)

	var nJSON []types.NetworkResource
	err = json.NewDecoder(body).Decode(&nJSON)
	assert.NilError(c, err)

	for _, n := range nJSON {
		if n.Name == name {
			return true
		}
	}
	return false
}

func getNetworkIDByName(c *testing.T, name string) string {
	filterJSON, err := filters.ToJSON(filters.NewArgs(filters.Arg("name", name)))
	assert.NilError(c, err)
	v := url.Values{}
	v.Set("filters", filterJSON)

	resp, body, err := request.Get("/networks?" + v.Encode())
	assert.Equal(c, resp.StatusCode, http.StatusOK)
	assert.NilError(c, err)

	var nJSON []types.NetworkResource
	err = json.NewDecoder(body).Decode(&nJSON)
	assert.NilError(c, err)
	var res string
	for _, n := range nJSON {
		// Find exact match
		if n.Name == name {
			res = n.ID
		}
	}
	assert.Assert(c, res != "")

	return res
}

func getNetworkResource(c *testing.T, id string) *types.NetworkResource {
	_, obj, err := request.Get("/networks/" + id)
	assert.NilError(c, err)

	nr := types.NetworkResource{}
	err = json.NewDecoder(obj).Decode(&nr)
	assert.NilError(c, err)

	return &nr
}

func createNetwork(c *testing.T, config types.NetworkCreateRequest, expectedStatusCode int) string {
	resp, body, err := request.Post("/networks/create", request.JSONBody(config))
	assert.NilError(c, err)
	defer resp.Body.Close()

	if expectedStatusCode >= 0 {
		assert.Equal(c, resp.StatusCode, expectedStatusCode)
	} else {
		assert.Assert(c, resp.StatusCode != -expectedStatusCode)
	}

	if expectedStatusCode == http.StatusCreated || expectedStatusCode < 0 {
		var nr types.NetworkCreateResponse
		err = json.NewDecoder(body).Decode(&nr)
		assert.NilError(c, err)

		return nr.ID
	}
	return ""
}

func connectNetwork(c *testing.T, nid, cid string) {
	config := types.NetworkConnect{
		Container: cid,
	}

	resp, _, err := request.Post("/networks/"+nid+"/connect", request.JSONBody(config))
	assert.Equal(c, resp.StatusCode, http.StatusOK)
	assert.NilError(c, err)
}

func disconnectNetwork(c *testing.T, nid, cid string) {
	config := types.NetworkConnect{
		Container: cid,
	}

	resp, _, err := request.Post("/networks/"+nid+"/disconnect", request.JSONBody(config))
	assert.Equal(c, resp.StatusCode, http.StatusOK)
	assert.NilError(c, err)
}

func deleteNetwork(c *testing.T, id string, shouldSucceed bool) {
	resp, _, err := request.Delete("/networks/" + id)
	assert.NilError(c, err)
	defer resp.Body.Close()
	if !shouldSucceed {
		assert.Assert(c, resp.StatusCode != http.StatusOK)
		return
	}
	assert.Equal(c, resp.StatusCode, http.StatusNoContent)
}
