package containerd // import "github.com/docker/docker/plugin/executor/containerd"

import (
	"context"
	"io"
	"sync"

	"github.com/containerd/containerd"
	"github.com/containerd/containerd/cio"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/errdefs"
	"github.com/docker/docker/libcontainerd"
	libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
	specs "github.com/opencontainers/runtime-spec/specs-go"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

// PluginNamespace is the name used for the plugins namespace
const PluginNamespace = "plugins.moby"

// ExitHandler represents an object that is called when the exit event is received from containerd
type ExitHandler interface {
	HandleExitEvent(id string) error
}

// New creates a new containerd plugin executor
func New(ctx context.Context, rootDir string, cli *containerd.Client, ns string, exitHandler ExitHandler, runtime types.Runtime) (*Executor, error) {
	e := &Executor{
		rootDir:     rootDir,
		exitHandler: exitHandler,
		runtime:     runtime,
	}

	client, err := libcontainerd.NewClient(ctx, cli, rootDir, ns, e)
	if err != nil {
		return nil, errors.Wrap(err, "error creating containerd exec client")
	}
	e.client = client
	return e, nil
}

// Executor is the containerd client implementation of a plugin executor
type Executor struct {
	rootDir     string
	client      libcontainerdtypes.Client
	exitHandler ExitHandler
	runtime     types.Runtime
}

// deleteTaskAndContainer deletes plugin task and then plugin container from containerd
func deleteTaskAndContainer(ctx context.Context, cli libcontainerdtypes.Client, id string, p libcontainerdtypes.Process) {
	if p != nil {
		if _, _, err := p.Delete(ctx); err != nil && !errdefs.IsNotFound(err) {
			logrus.WithError(err).WithField("id", id).Error("failed to delete plugin task from containerd")
		}
	} else {
		if _, _, err := cli.DeleteTask(ctx, id); err != nil && !errdefs.IsNotFound(err) {
			logrus.WithError(err).WithField("id", id).Error("failed to delete plugin task from containerd")
		}
	}

	if err := cli.Delete(ctx, id); err != nil && !errdefs.IsNotFound(err) {
		logrus.WithError(err).WithField("id", id).Error("failed to delete plugin container from containerd")
	}
}

// Create creates a new container
func (e *Executor) Create(id string, spec specs.Spec, stdout, stderr io.WriteCloser) error {
	ctx := context.Background()
	err := e.client.Create(ctx, id, &spec, e.runtime.Shim.Binary, e.runtime.Shim.Opts)
	if err != nil {
		status, err2 := e.client.Status(ctx, id)
		if err2 != nil {
			if !errdefs.IsNotFound(err2) {
				logrus.WithError(err2).WithField("id", id).Warn("Received an error while attempting to read plugin status")
			}
		} else {
			if status != containerd.Running && status != containerd.Unknown {
				if err2 := e.client.Delete(ctx, id); err2 != nil && !errdefs.IsNotFound(err2) {
					logrus.WithError(err2).WithField("plugin", id).Error("Error cleaning up containerd container")
				}
				err = e.client.Create(ctx, id, &spec, e.runtime.Shim.Binary, e.runtime.Shim.Opts)
			}
		}

		if err != nil {
			return errors.Wrap(err, "error creating containerd container")
		}
	}

	_, err = e.client.Start(ctx, id, "", false, attachStreamsFunc(stdout, stderr))
	if err != nil {
		deleteTaskAndContainer(ctx, e.client, id, nil)
	}
	return err
}

// Restore restores a container
func (e *Executor) Restore(id string, stdout, stderr io.WriteCloser) (bool, error) {
	alive, _, p, err := e.client.Restore(context.Background(), id, attachStreamsFunc(stdout, stderr))
	if err != nil && !errdefs.IsNotFound(err) {
		return false, err
	}
	if !alive {
		deleteTaskAndContainer(context.Background(), e.client, id, p)
	}
	return alive, nil
}

// IsRunning returns if the container with the given id is running
func (e *Executor) IsRunning(id string) (bool, error) {
	status, err := e.client.Status(context.Background(), id)
	return status == containerd.Running, err
}

// Signal sends the specified signal to the container
func (e *Executor) Signal(id string, signal int) error {
	return e.client.SignalProcess(context.Background(), id, libcontainerdtypes.InitProcessName, signal)
}

// ProcessEvent handles events from containerd
// All events are ignored except the exit event, which is sent of to the stored handler
func (e *Executor) ProcessEvent(id string, et libcontainerdtypes.EventType, ei libcontainerdtypes.EventInfo) error {
	switch et {
	case libcontainerdtypes.EventExit:
		deleteTaskAndContainer(context.Background(), e.client, id, nil)
		return e.exitHandler.HandleExitEvent(ei.ContainerID)
	}
	return nil
}

type rio struct {
	cio.IO

	wg sync.WaitGroup
}

func (c *rio) Wait() {
	c.wg.Wait()
	c.IO.Wait()
}

func attachStreamsFunc(stdout, stderr io.WriteCloser) libcontainerdtypes.StdioCallback {
	return func(iop *cio.DirectIO) (cio.IO, error) {
		if iop.Stdin != nil {
			iop.Stdin.Close()
			// closing stdin shouldn't be needed here, it should never be open
			panic("plugin stdin shouldn't have been created!")
		}

		rio := &rio{IO: iop}
		rio.wg.Add(2)
		go func() {
			io.Copy(stdout, iop.Stdout)
			stdout.Close()
			rio.wg.Done()
		}()
		go func() {
			io.Copy(stderr, iop.Stderr)
			stderr.Close()
			rio.wg.Done()
		}()
		return rio, nil
	}
}
