// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package main

import (
	"bytes"
	"context"
	"errors"
	"io"
	"io/ioutil"
	"testing"
	"time"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/events"
	"github.com/docker/docker/api/types/network"
	"github.com/docker/docker/client"
)

// mockedCommonAPIClient provides mock implementations of Docker client methods needed by Pool.
type mockedCommonAPIClient struct {
	client.CommonAPIClient
	containers map[string]bool
	messages   chan events.Message
	errors     chan error
}

func (m *mockedCommonAPIClient) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error) {
	return container.ContainerCreateCreatedBody{ID: "test"}, nil
}

func (m *mockedCommonAPIClient) ContainerStart(ctx context.Context, containerID string, options types.ContainerStartOptions) error {
	if containerID != "test" {
		return errors.New("invalid ID")
	}
	return nil
}

func (m *mockedCommonAPIClient) Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) {
	return m.messages, m.errors
}

func (m *mockedCommonAPIClient) ContainerRestart(ctx context.Context, containerID string, timeout *time.Duration) error {
	if containerID != "test" {
		return errors.New("invalid ID")
	}
	return nil
}

func (m *mockedCommonAPIClient) ContainerStop(ctx context.Context, containerID string, timeout *time.Duration) error {
	if containerID != "test" {
		return errors.New("invalid ID")
	}
	return nil
}

func (m *mockedCommonAPIClient) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) {
	msgs := make(chan container.ContainerWaitOKBody, 1)
	msgs <- container.ContainerWaitOKBody{StatusCode: 0}
	errs := make(chan error, 0)
	return msgs, errs
}

func (m *mockedCommonAPIClient) ContainerRemove(ctx context.Context, containerID string, options types.ContainerRemoveOptions) error {
	if containerID != "test" {
		return errors.New("invalid ID")
	}
	return nil
}

func (m *mockedCommonAPIClient) ContainerKill(ctx context.Context, container, signal string) error {
	return nil
}

// mockedImageAPIClient provides mock implementations of Docker client methods needed by imagePull.
type mockedImageAPIClient struct {
	client.ImageAPIClient
	images map[string]types.ImageSummary
}

func (m *mockedImageAPIClient) ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) {
	reference := options.Filters.Get("reference")
	images := []types.ImageSummary{}
	for _, r := range reference {
		if image, ok := m.images[r]; ok {
			images = append(images, image)
		}
	}
	return images, nil
}

func (m *mockedImageAPIClient) ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error) {
	if _, ok := m.images[ref]; !ok {
		return nil, errors.New("image does not exist")
	}
	return ioutil.NopCloser(bytes.NewReader([]byte(`{"status": "done"}`))), nil
}

func TestImage(t *testing.T) {
	ctx := context.Background()

	mockClient := mockedImageAPIClient{
		images: map[string]types.ImageSummary{
			registryDomain + "/foo/bar": types.ImageSummary{},
		},
	}

	t.Run("image exists", func(t *testing.T) {
		image := NewImage(&mockClient)
		if err := image.Pull(ctx, "foo", "bar", "key"); err != nil {
			t.Error("image pull failed", err)
		}
	})

	t.Run("image does not exists", func(t *testing.T) {
		mockClient := mockedImageAPIClient{}
		image := NewImage(&mockClient)
		if err := image.Pull(ctx, "foo", "baz", "key"); err == nil {
			t.Error("image pull didn't fail", err)
		}
	})
}

func TestPool(t *testing.T) {
	ctx := context.Background()

	// TODO: test behavior with multiple containers
	containers := []*Container{&Container{
		Name:       "test",
		hostname:   "test--test001",
		domainname: "local",
		workdir:    "/b/test001",
		cpuset:     "0-1",
	}}

	t.Run("pool create, restart and remove", func(t *testing.T) {
		msgs := make(chan events.Message, 1)
		errs := make(chan error, 1)
		mockClient := mockedCommonAPIClient{
			containers: map[string]bool{
				"test--test001": true,
			},
			messages: msgs,
			errors:   errs,
		}

		pool := NewPool(&mockClient)
		if err := <-pool.Create(ctx, containers); err != nil {
			t.Error("pool creation failed", err)
		}
		pool.Serve(ctx)
		mockClient.messages <- events.Message{
			Action: "die",
			Actor: events.Actor{
				Attributes: map[string]string{
					"name": "test",
				},
			},
		}
		for err := range pool.Remove(ctx) {
			t.Error("pool removal failed", err)
		}
	})

	t.Run("pool create, drain and remove", func(t *testing.T) {
		mockClient := mockedCommonAPIClient{
			containers: map[string]bool{
				"test--test001": true,
			},
		}

		pool := NewPool(&mockClient)
		if err := <-pool.Create(ctx, containers); err != nil {
			t.Error("pool creation failed", err)
		}
		pool.Serve(ctx)
		for err := range pool.Drain(ctx) {
			t.Error("pool drain failed", err)
		}
		for err := range pool.Remove(ctx) {
			t.Error("pool removal failed", err)
		}
	})
}
