package daemon

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"time"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/filters"
	"github.com/docker/docker/api/types/swarm"
	"github.com/docker/docker/integration-cli/checker"
	"github.com/go-check/check"
	"github.com/pkg/errors"
	"golang.org/x/net/context"
)

// Swarm is a test daemon with helpers for participating in a swarm.
type Swarm struct {
	*Daemon
	swarm.Info
	Port       int
	ListenAddr string
}

// Init initializes a new swarm cluster.
func (d *Swarm) Init(req swarm.InitRequest) error {
	if req.ListenAddr == "" {
		req.ListenAddr = d.ListenAddr
	}
	cli, err := d.NewClient()
	if err != nil {
		return fmt.Errorf("initializing swarm: failed to create client %v", err)
	}
	defer cli.Close()
	_, err = cli.SwarmInit(context.Background(), req)
	if err != nil {
		return fmt.Errorf("initializing swarm: %v", err)
	}
	info, err := d.SwarmInfo()
	if err != nil {
		return err
	}
	d.Info = info
	return nil
}

// Join joins a daemon to an existing cluster.
func (d *Swarm) Join(req swarm.JoinRequest) error {
	if req.ListenAddr == "" {
		req.ListenAddr = d.ListenAddr
	}
	cli, err := d.NewClient()
	if err != nil {
		return fmt.Errorf("joining swarm: failed to create client %v", err)
	}
	defer cli.Close()
	err = cli.SwarmJoin(context.Background(), req)
	if err != nil {
		return fmt.Errorf("joining swarm: %v", err)
	}
	info, err := d.SwarmInfo()
	if err != nil {
		return err
	}
	d.Info = info
	return nil
}

// Leave forces daemon to leave current cluster.
func (d *Swarm) Leave(force bool) error {
	cli, err := d.NewClient()
	if err != nil {
		return fmt.Errorf("leaving swarm: failed to create client %v", err)
	}
	defer cli.Close()
	err = cli.SwarmLeave(context.Background(), force)
	if err != nil {
		err = fmt.Errorf("leaving swarm: %v", err)
	}
	return err
}

// SwarmInfo returns the swarm information of the daemon
func (d *Swarm) SwarmInfo() (swarm.Info, error) {
	cli, err := d.NewClient()
	if err != nil {
		return swarm.Info{}, fmt.Errorf("get swarm info: %v", err)
	}

	info, err := cli.Info(context.Background())
	if err != nil {
		return swarm.Info{}, fmt.Errorf("get swarm info: %v", err)
	}

	return info.Swarm, nil
}

// Unlock tries to unlock a locked swarm
func (d *Swarm) Unlock(req swarm.UnlockRequest) error {
	cli, err := d.NewClient()
	if err != nil {
		return fmt.Errorf("unlocking swarm: failed to create client %v", err)
	}
	defer cli.Close()
	err = cli.SwarmUnlock(context.Background(), req)
	if err != nil {
		err = errors.Wrap(err, "unlocking swarm")
	}
	return err
}

// ServiceConstructor defines a swarm service constructor function
type ServiceConstructor func(*swarm.Service)

// NodeConstructor defines a swarm node constructor
type NodeConstructor func(*swarm.Node)

// SecretConstructor defines a swarm secret constructor
type SecretConstructor func(*swarm.Secret)

// ConfigConstructor defines a swarm config constructor
type ConfigConstructor func(*swarm.Config)

// SpecConstructor defines a swarm spec constructor
type SpecConstructor func(*swarm.Spec)

// CreateServiceWithOptions creates a swarm service given the specified service constructors
// and auth config
func (d *Swarm) CreateServiceWithOptions(c *check.C, opts types.ServiceCreateOptions, f ...ServiceConstructor) string {
	var service swarm.Service
	for _, fn := range f {
		fn(&service)
	}

	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	res, err := cli.ServiceCreate(ctx, service.Spec, opts)
	c.Assert(err, checker.IsNil)
	return res.ID
}

// CreateService creates a swarm service given the specified service constructor
func (d *Swarm) CreateService(c *check.C, f ...ServiceConstructor) string {
	return d.CreateServiceWithOptions(c, types.ServiceCreateOptions{}, f...)
}

// GetService returns the swarm service corresponding to the specified id
func (d *Swarm) GetService(c *check.C, id string) *swarm.Service {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	service, _, err := cli.ServiceInspectWithRaw(context.Background(), id, types.ServiceInspectOptions{})
	c.Assert(err, checker.IsNil)
	return &service
}

// GetServiceTasks returns the swarm tasks for the specified service
func (d *Swarm) GetServiceTasks(c *check.C, service string) []swarm.Task {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	filterArgs := filters.NewArgs()
	filterArgs.Add("desired-state", "running")
	filterArgs.Add("service", service)

	options := types.TaskListOptions{
		Filters: filterArgs,
	}

	tasks, err := cli.TaskList(context.Background(), options)
	c.Assert(err, checker.IsNil)
	return tasks
}

// CheckServiceTasksInState returns the number of tasks with a matching state,
// and optional message substring.
func (d *Swarm) CheckServiceTasksInState(service string, state swarm.TaskState, message string) func(*check.C) (interface{}, check.CommentInterface) {
	return func(c *check.C) (interface{}, check.CommentInterface) {
		tasks := d.GetServiceTasks(c, service)
		var count int
		for _, task := range tasks {
			if task.Status.State == state {
				if message == "" || strings.Contains(task.Status.Message, message) {
					count++
				}
			}
		}
		return count, nil
	}
}

// CheckServiceTasksInStateWithError returns the number of tasks with a matching state,
// and optional message substring.
func (d *Swarm) CheckServiceTasksInStateWithError(service string, state swarm.TaskState, errorMessage string) func(*check.C) (interface{}, check.CommentInterface) {
	return func(c *check.C) (interface{}, check.CommentInterface) {
		tasks := d.GetServiceTasks(c, service)
		var count int
		for _, task := range tasks {
			if task.Status.State == state {
				if errorMessage == "" || strings.Contains(task.Status.Err, errorMessage) {
					count++
				}
			}
		}
		return count, nil
	}
}

// CheckServiceRunningTasks returns the number of running tasks for the specified service
func (d *Swarm) CheckServiceRunningTasks(service string) func(*check.C) (interface{}, check.CommentInterface) {
	return d.CheckServiceTasksInState(service, swarm.TaskStateRunning, "")
}

// CheckServiceUpdateState returns the current update state for the specified service
func (d *Swarm) CheckServiceUpdateState(service string) func(*check.C) (interface{}, check.CommentInterface) {
	return func(c *check.C) (interface{}, check.CommentInterface) {
		service := d.GetService(c, service)
		if service.UpdateStatus == nil {
			return "", nil
		}
		return service.UpdateStatus.State, nil
	}
}

// CheckPluginRunning returns the runtime state of the plugin
func (d *Swarm) CheckPluginRunning(plugin string) func(c *check.C) (interface{}, check.CommentInterface) {
	return func(c *check.C) (interface{}, check.CommentInterface) {
		status, out, err := d.SockRequest("GET", "/plugins/"+plugin+"/json", nil)
		c.Assert(err, checker.IsNil, check.Commentf(string(out)))
		if status != http.StatusOK {
			return false, nil
		}

		var p types.Plugin
		c.Assert(json.Unmarshal(out, &p), checker.IsNil, check.Commentf(string(out)))

		return p.Enabled, check.Commentf("%+v", p)
	}
}

// CheckPluginImage returns the runtime state of the plugin
func (d *Swarm) CheckPluginImage(plugin string) func(c *check.C) (interface{}, check.CommentInterface) {
	return func(c *check.C) (interface{}, check.CommentInterface) {
		status, out, err := d.SockRequest("GET", "/plugins/"+plugin+"/json", nil)
		c.Assert(err, checker.IsNil, check.Commentf(string(out)))
		if status != http.StatusOK {
			return false, nil
		}

		var p types.Plugin
		c.Assert(json.Unmarshal(out, &p), checker.IsNil, check.Commentf(string(out)))
		return p.PluginReference, check.Commentf("%+v", p)
	}
}

// CheckServiceTasks returns the number of tasks for the specified service
func (d *Swarm) CheckServiceTasks(service string) func(*check.C) (interface{}, check.CommentInterface) {
	return func(c *check.C) (interface{}, check.CommentInterface) {
		tasks := d.GetServiceTasks(c, service)
		return len(tasks), nil
	}
}

// CheckRunningTaskNetworks returns the number of times each network is referenced from a task.
func (d *Swarm) CheckRunningTaskNetworks(c *check.C) (interface{}, check.CommentInterface) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	filterArgs := filters.NewArgs()
	filterArgs.Add("desired-state", "running")

	options := types.TaskListOptions{
		Filters: filterArgs,
	}

	tasks, err := cli.TaskList(context.Background(), options)
	c.Assert(err, checker.IsNil)

	result := make(map[string]int)
	for _, task := range tasks {
		for _, network := range task.Spec.Networks {
			result[network.Target]++
		}
	}
	return result, nil
}

// CheckRunningTaskImages returns the times each image is running as a task.
func (d *Swarm) CheckRunningTaskImages(c *check.C) (interface{}, check.CommentInterface) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	filterArgs := filters.NewArgs()
	filterArgs.Add("desired-state", "running")

	options := types.TaskListOptions{
		Filters: filterArgs,
	}

	tasks, err := cli.TaskList(context.Background(), options)
	c.Assert(err, checker.IsNil)

	result := make(map[string]int)
	for _, task := range tasks {
		if task.Status.State == swarm.TaskStateRunning && task.Spec.ContainerSpec != nil {
			result[task.Spec.ContainerSpec.Image]++
		}
	}
	return result, nil
}

// CheckNodeReadyCount returns the number of ready node on the swarm
func (d *Swarm) CheckNodeReadyCount(c *check.C) (interface{}, check.CommentInterface) {
	nodes := d.ListNodes(c)
	var readyCount int
	for _, node := range nodes {
		if node.Status.State == swarm.NodeStateReady {
			readyCount++
		}
	}
	return readyCount, nil
}

// GetTask returns the swarm task identified by the specified id
func (d *Swarm) GetTask(c *check.C, id string) swarm.Task {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	task, _, err := cli.TaskInspectWithRaw(context.Background(), id)
	c.Assert(err, checker.IsNil)
	return task
}

// UpdateService updates a swarm service with the specified service constructor
func (d *Swarm) UpdateService(c *check.C, service *swarm.Service, f ...ServiceConstructor) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	for _, fn := range f {
		fn(service)
	}

	_, err = cli.ServiceUpdate(context.Background(), service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{})
	c.Assert(err, checker.IsNil)
}

// RemoveService removes the specified service
func (d *Swarm) RemoveService(c *check.C, id string) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	err = cli.ServiceRemove(context.Background(), id)
	c.Assert(err, checker.IsNil)
}

// GetNode returns a swarm node identified by the specified id
func (d *Swarm) GetNode(c *check.C, id string) *swarm.Node {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	node, _, err := cli.NodeInspectWithRaw(context.Background(), id)
	c.Assert(err, checker.IsNil)
	c.Assert(node.ID, checker.Equals, id)
	return &node
}

// RemoveNode removes the specified node
func (d *Swarm) RemoveNode(c *check.C, id string, force bool) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	options := types.NodeRemoveOptions{
		Force: force,
	}
	err = cli.NodeRemove(context.Background(), id, options)
	c.Assert(err, checker.IsNil)
}

// UpdateNode updates a swarm node with the specified node constructor
func (d *Swarm) UpdateNode(c *check.C, id string, f ...NodeConstructor) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	for i := 0; ; i++ {
		node := d.GetNode(c, id)
		for _, fn := range f {
			fn(node)
		}

		err = cli.NodeUpdate(context.Background(), node.ID, node.Version, node.Spec)
		if i < 10 && err != nil && strings.Contains(err.Error(), "update out of sequence") {
			time.Sleep(100 * time.Millisecond)
			continue
		}
		c.Assert(err, checker.IsNil)
		return
	}
}

// ListNodes returns the list of the current swarm nodes
func (d *Swarm) ListNodes(c *check.C) []swarm.Node {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	nodes, err := cli.NodeList(context.Background(), types.NodeListOptions{})
	c.Assert(err, checker.IsNil)

	return nodes
}

// ListServices returns the list of the current swarm services
func (d *Swarm) ListServices(c *check.C) []swarm.Service {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	services, err := cli.ServiceList(context.Background(), types.ServiceListOptions{})
	c.Assert(err, checker.IsNil)
	return services
}

// CreateSecret creates a secret given the specified spec
func (d *Swarm) CreateSecret(c *check.C, secretSpec swarm.SecretSpec) string {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	scr, err := cli.SecretCreate(context.Background(), secretSpec)
	c.Assert(err, checker.IsNil)

	return scr.ID
}

// ListSecrets returns the list of the current swarm secrets
func (d *Swarm) ListSecrets(c *check.C) []swarm.Secret {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	secrets, err := cli.SecretList(context.Background(), types.SecretListOptions{})
	c.Assert(err, checker.IsNil)
	return secrets
}

// GetSecret returns a swarm secret identified by the specified id
func (d *Swarm) GetSecret(c *check.C, id string) *swarm.Secret {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	secret, _, err := cli.SecretInspectWithRaw(context.Background(), id)
	c.Assert(err, checker.IsNil)
	return &secret
}

// DeleteSecret removes the swarm secret identified by the specified id
func (d *Swarm) DeleteSecret(c *check.C, id string) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	err = cli.SecretRemove(context.Background(), id)
	c.Assert(err, checker.IsNil)
}

// UpdateSecret updates the swarm secret identified by the specified id
// Currently, only label update is supported.
func (d *Swarm) UpdateSecret(c *check.C, id string, f ...SecretConstructor) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	secret := d.GetSecret(c, id)
	for _, fn := range f {
		fn(secret)
	}

	err = cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec)

	c.Assert(err, checker.IsNil)
}

// CreateConfig creates a config given the specified spec
func (d *Swarm) CreateConfig(c *check.C, configSpec swarm.ConfigSpec) string {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	scr, err := cli.ConfigCreate(context.Background(), configSpec)
	c.Assert(err, checker.IsNil)
	return scr.ID
}

// ListConfigs returns the list of the current swarm configs
func (d *Swarm) ListConfigs(c *check.C) []swarm.Config {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	configs, err := cli.ConfigList(context.Background(), types.ConfigListOptions{})
	c.Assert(err, checker.IsNil)
	return configs
}

// GetConfig returns a swarm config identified by the specified id
func (d *Swarm) GetConfig(c *check.C, id string) *swarm.Config {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	config, _, err := cli.ConfigInspectWithRaw(context.Background(), id)
	c.Assert(err, checker.IsNil)
	return &config
}

// DeleteConfig removes the swarm config identified by the specified id
func (d *Swarm) DeleteConfig(c *check.C, id string) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	err = cli.ConfigRemove(context.Background(), id)
	c.Assert(err, checker.IsNil)
}

// UpdateConfig updates the swarm config identified by the specified id
// Currently, only label update is supported.
func (d *Swarm) UpdateConfig(c *check.C, id string, f ...ConfigConstructor) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	config := d.GetConfig(c, id)
	for _, fn := range f {
		fn(config)
	}

	err = cli.ConfigUpdate(context.Background(), config.ID, config.Version, config.Spec)
	c.Assert(err, checker.IsNil)
}

// GetSwarm returns the current swarm object
func (d *Swarm) GetSwarm(c *check.C) swarm.Swarm {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	sw, err := cli.SwarmInspect(context.Background())
	c.Assert(err, checker.IsNil)
	return sw
}

// UpdateSwarm updates the current swarm object with the specified spec constructors
func (d *Swarm) UpdateSwarm(c *check.C, f ...SpecConstructor) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	sw := d.GetSwarm(c)
	for _, fn := range f {
		fn(&sw.Spec)
	}

	err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, swarm.UpdateFlags{})
	c.Assert(err, checker.IsNil)
}

// RotateTokens update the swarm to rotate tokens
func (d *Swarm) RotateTokens(c *check.C) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	sw, err := cli.SwarmInspect(context.Background())
	c.Assert(err, checker.IsNil)

	flags := swarm.UpdateFlags{
		RotateManagerToken: true,
		RotateWorkerToken:  true,
	}

	err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, flags)
	c.Assert(err, checker.IsNil)
}

// JoinTokens returns the current swarm join tokens
func (d *Swarm) JoinTokens(c *check.C) swarm.JoinTokens {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	sw, err := cli.SwarmInspect(context.Background())
	c.Assert(err, checker.IsNil)
	return sw.JoinTokens
}

// CheckLocalNodeState returns the current swarm node state
func (d *Swarm) CheckLocalNodeState(c *check.C) (interface{}, check.CommentInterface) {
	info, err := d.SwarmInfo()
	c.Assert(err, checker.IsNil)
	return info.LocalNodeState, nil
}

// CheckControlAvailable returns the current swarm control available
func (d *Swarm) CheckControlAvailable(c *check.C) (interface{}, check.CommentInterface) {
	info, err := d.SwarmInfo()
	c.Assert(err, checker.IsNil)
	c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
	return info.ControlAvailable, nil
}

// CheckLeader returns whether there is a leader on the swarm or not
func (d *Swarm) CheckLeader(c *check.C) (interface{}, check.CommentInterface) {
	cli, err := d.NewClient()
	c.Assert(err, checker.IsNil)
	defer cli.Close()

	errList := check.Commentf("could not get node list")

	ls, err := cli.NodeList(context.Background(), types.NodeListOptions{})
	if err != nil {
		return err, errList
	}

	for _, node := range ls {
		if node.ManagerStatus != nil && node.ManagerStatus.Leader {
			return nil, nil
		}
	}
	return fmt.Errorf("no leader"), check.Commentf("could not find leader")
}

// CmdRetryOutOfSequence tries the specified command against the current daemon for 10 times
func (d *Swarm) CmdRetryOutOfSequence(args ...string) (string, error) {
	for i := 0; ; i++ {
		out, err := d.Cmd(args...)
		if err != nil {
			if strings.Contains(out, "update out of sequence") {
				if i < 10 {
					continue
				}
			}
		}
		return out, err
	}
}
