// +build linux

package linux

import (
	"context"

	"github.com/containerd/containerd/api/services/shim"
	"github.com/containerd/containerd/api/types/task"
	"github.com/containerd/containerd/plugin"
	protobuf "github.com/gogo/protobuf/types"
	specs "github.com/opencontainers/runtime-spec/specs-go"
)

type State struct {
	pid    uint32
	status plugin.Status
}

func (s State) Pid() uint32 {
	return s.pid
}

func (s State) Status() plugin.Status {
	return s.status
}

type Task struct {
	containerID string
	spec        []byte
	shim        shim.ShimClient
}

func newTask(id string, spec []byte, shim shim.ShimClient) *Task {
	return &Task{
		containerID: id,
		shim:        shim,
		spec:        spec,
	}
}

func (c *Task) Info() plugin.TaskInfo {
	return plugin.TaskInfo{
		ID:          c.containerID,
		ContainerID: c.containerID,
		Runtime:     runtimeName,
		Spec:        c.spec,
	}
}

func (c *Task) Start(ctx context.Context) error {
	_, err := c.shim.Start(ctx, &shim.StartRequest{})
	return err
}

func (c *Task) State(ctx context.Context) (plugin.State, error) {
	response, err := c.shim.State(ctx, &shim.StateRequest{})
	if err != nil {
		return nil, err
	}
	var status plugin.Status
	switch response.Status {
	case task.StatusCreated:
		status = plugin.CreatedStatus
	case task.StatusRunning:
		status = plugin.RunningStatus
	case task.StatusStopped:
		status = plugin.StoppedStatus
	case task.StatusPaused:
		status = plugin.PausedStatus
		// TODO: containerd.DeletedStatus
	}
	return &State{
		pid:    response.Pid,
		status: status,
	}, nil
}

func (c *Task) Pause(ctx context.Context) error {
	_, err := c.shim.Pause(ctx, &shim.PauseRequest{})
	return err
}

func (c *Task) Resume(ctx context.Context) error {
	_, err := c.shim.Resume(ctx, &shim.ResumeRequest{})
	return err
}

func (c *Task) Kill(ctx context.Context, signal uint32, pid uint32, all bool) error {
	_, err := c.shim.Kill(ctx, &shim.KillRequest{
		Signal: signal,
		Pid:    pid,
		All:    all,
	})
	return err
}

func (c *Task) Exec(ctx context.Context, opts plugin.ExecOpts) (plugin.Process, error) {
	request := &shim.ExecRequest{
		Stdin:    opts.IO.Stdin,
		Stdout:   opts.IO.Stdout,
		Stderr:   opts.IO.Stderr,
		Terminal: opts.IO.Terminal,
		Spec: &protobuf.Any{
			TypeUrl: specs.Version,
			Value:   opts.Spec,
		},
	}
	resp, err := c.shim.Exec(ctx, request)
	if err != nil {
		return nil, err

	}
	return &Process{
		pid: int(resp.Pid),
		c:   c,
	}, nil
}

func (c *Task) Processes(ctx context.Context) ([]uint32, error) {
	resp, err := c.shim.Processes(ctx, &shim.ProcessesRequest{
		ID: c.containerID,
	})

	if err != nil {
		return nil, err
	}

	pids := make([]uint32, 0, len(resp.Processes))

	for _, ps := range resp.Processes {
		pids = append(pids, ps.Pid)
	}

	return pids, nil
}

func (c *Task) Pty(ctx context.Context, pid uint32, size plugin.ConsoleSize) error {
	_, err := c.shim.Pty(ctx, &shim.PtyRequest{
		Pid:    pid,
		Width:  size.Width,
		Height: size.Height,
	})
	return err
}

func (c *Task) CloseStdin(ctx context.Context, pid uint32) error {
	_, err := c.shim.CloseStdin(ctx, &shim.CloseStdinRequest{
		Pid: pid,
	})
	return err
}

func (c *Task) Checkpoint(ctx context.Context, opts plugin.CheckpointOpts) error {
	_, err := c.shim.Checkpoint(ctx, &shim.CheckpointRequest{
		Exit:             opts.Exit,
		AllowTcp:         opts.AllowTCP,
		AllowUnixSockets: opts.AllowUnixSockets,
		AllowTerminal:    opts.AllowTerminal,
		FileLocks:        opts.FileLocks,
		EmptyNamespaces:  opts.EmptyNamespaces,
		Image:            opts.Path,
	})
	return err
}

type Process struct {
	pid int
	c   *Task
}

func (p *Process) Kill(ctx context.Context, signal uint32, _ bool) error {
	_, err := p.c.shim.Kill(ctx, &shim.KillRequest{
		Signal: signal,
		Pid:    uint32(p.pid),
	})
	return err
}

func (p *Process) State(ctx context.Context) (plugin.State, error) {
	// use the container status for the status of the process
	state, err := p.c.State(ctx)
	if err != nil {
		return nil, err
	}
	state.(*State).pid = uint32(p.pid)
	return state, nil
}
