// +build experimental

package libcontainerd

import (
	"fmt"

	"github.com/Sirupsen/logrus"
	containerd "github.com/docker/containerd/api/grpc/types"
)

func (clnt *client) restore(cont *containerd.Container, options ...CreateOption) (err error) {
	clnt.lock(cont.Id)
	defer clnt.unlock(cont.Id)

	logrus.Debugf("restore container %s state %s", cont.Id, cont.Status)

	containerID := cont.Id
	if _, err := clnt.getContainer(containerID); err == nil {
		return fmt.Errorf("container %s is aleady active", containerID)
	}

	defer func() {
		if err != nil {
			clnt.deleteContainer(cont.Id)
		}
	}()

	container := clnt.newContainer(cont.BundlePath, options...)
	container.systemPid = systemPid(cont)

	var terminal bool
	for _, p := range cont.Processes {
		if p.Pid == InitFriendlyName {
			terminal = p.Terminal
		}
	}

	iopipe, err := container.openFifos(terminal)
	if err != nil {
		return err
	}

	if err := clnt.backend.AttachStreams(containerID, *iopipe); err != nil {
		return err
	}

	clnt.appendContainer(container)

	err = clnt.backend.StateChanged(containerID, StateInfo{
		State: StateRestore,
		Pid:   container.systemPid,
	})

	if err != nil {
		return err
	}

	if event, ok := clnt.remote.pastEvents[containerID]; ok {
		// This should only be a pause or resume event
		if event.Type == StatePause || event.Type == StateResume {
			return clnt.backend.StateChanged(containerID, StateInfo{
				State: event.Type,
				Pid:   container.systemPid,
			})
		}

		logrus.Warnf("unexpected backlog event: %#v", event)
	}

	return nil
}

func (clnt *client) Restore(containerID string, options ...CreateOption) error {
	cont, err := clnt.getContainerdContainer(containerID)
	if err == nil && cont.Status != "stopped" {
		if err := clnt.restore(cont, options...); err != nil {
			logrus.Errorf("error restoring %s: %v", containerID, err)
		}
		return nil
	}
	return clnt.setExited(containerID)
}