package daemon

import (
	"fmt"
	"strings"
	"syscall"

	"github.com/pkg/errors"
	"google.golang.org/grpc"
)

func errNotRunning(id string) error {
	return stateConflictError{errors.Errorf("Container %s is not running", id)}
}

func containerNotFound(id string) error {
	return objNotFoundError{"container", id}
}

func volumeNotFound(id string) error {
	return objNotFoundError{"volume", id}
}

func networkNotFound(id string) error {
	return objNotFoundError{"network", id}
}

type objNotFoundError struct {
	object string
	id     string
}

func (e objNotFoundError) Error() string {
	return "No such " + e.object + ": " + e.id
}

func (e objNotFoundError) NotFound() {}

type stateConflictError struct {
	cause error
}

func (e stateConflictError) Error() string {
	return e.cause.Error()
}

func (e stateConflictError) Cause() error {
	return e.cause
}

func (e stateConflictError) Conflict() {}

func errContainerIsRestarting(containerID string) error {
	cause := errors.Errorf("Container %s is restarting, wait until the container is running", containerID)
	return stateConflictError{cause}
}

func errExecNotFound(id string) error {
	return objNotFoundError{"exec instance", id}
}

func errExecPaused(id string) error {
	cause := errors.Errorf("Container %s is paused, unpause the container before exec", id)
	return stateConflictError{cause}
}

type nameConflictError struct {
	id   string
	name string
}

func (e nameConflictError) Error() string {
	return fmt.Sprintf("Conflict. The container name %q is already in use by container %q. You have to remove (or rename) that container to be able to reuse that name.", e.name, e.id)
}

func (nameConflictError) Conflict() {}

type validationError struct {
	cause error
}

func (e validationError) Error() string {
	return e.cause.Error()
}

func (e validationError) InvalidParameter() {}

func (e validationError) Cause() error {
	return e.cause
}

type notAllowedError struct {
	cause error
}

func (e notAllowedError) Error() string {
	return e.cause.Error()
}

func (e notAllowedError) Forbidden() {}

func (e notAllowedError) Cause() error {
	return e.cause
}

type containerNotModifiedError struct {
	running bool
}

func (e containerNotModifiedError) Error() string {
	if e.running {
		return "Container is already started"
	}
	return "Container is already stopped"
}

func (e containerNotModifiedError) NotModified() {}

type systemError struct {
	cause error
}

func (e systemError) Error() string {
	return e.cause.Error()
}

func (e systemError) SystemError() {}

func (e systemError) Cause() error {
	return e.cause
}

type invalidIdentifier string

func (e invalidIdentifier) Error() string {
	return fmt.Sprintf("invalid name or ID supplied: %q", string(e))
}

func (invalidIdentifier) InvalidParameter() {}

type duplicateMountPointError string

func (e duplicateMountPointError) Error() string {
	return "Duplicate mount point: " + string(e)
}
func (duplicateMountPointError) InvalidParameter() {}

type containerFileNotFound struct {
	file      string
	container string
}

func (e containerFileNotFound) Error() string {
	return "Could not find the file " + e.file + " in container " + e.container
}

func (containerFileNotFound) NotFound() {}

type invalidFilter struct {
	filter string
	value  interface{}
}

func (e invalidFilter) Error() string {
	msg := "Invalid filter '" + e.filter
	if e.value != nil {
		msg += fmt.Sprintf("=%s", e.value)
	}
	return msg + "'"
}

func (e invalidFilter) InvalidParameter() {}

type unknownError struct {
	cause error
}

func (e unknownError) Error() string {
	return e.cause.Error()
}

func (unknownError) Unknown() {}

func (e unknownError) Cause() error {
	return e.cause
}

type startInvalidConfigError string

func (e startInvalidConfigError) Error() string {
	return string(e)
}

func (e startInvalidConfigError) InvalidParameter() {} // Is this right???

func translateContainerdStartErr(cmd string, setExitCode func(int), err error) error {
	errDesc := grpc.ErrorDesc(err)
	contains := func(s1, s2 string) bool {
		return strings.Contains(strings.ToLower(s1), s2)
	}
	var retErr error = unknownError{errors.New(errDesc)}
	// if we receive an internal error from the initial start of a container then lets
	// return it instead of entering the restart loop
	// set to 127 for container cmd not found/does not exist)
	if contains(errDesc, cmd) &&
		(contains(errDesc, "executable file not found") ||
			contains(errDesc, "no such file or directory") ||
			contains(errDesc, "system cannot find the file specified")) {
		setExitCode(127)
		retErr = startInvalidConfigError(errDesc)
	}
	// set to 126 for container cmd can't be invoked errors
	if contains(errDesc, syscall.EACCES.Error()) {
		setExitCode(126)
		retErr = startInvalidConfigError(errDesc)
	}

	// attempted to mount a file onto a directory, or a directory onto a file, maybe from user specified bind mounts
	if contains(errDesc, syscall.ENOTDIR.Error()) {
		errDesc += ": Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type"
		setExitCode(127)
		retErr = startInvalidConfigError(errDesc)
	}

	// TODO: it would be nice to get some better errors from containerd so we can return better errors here
	return retErr
}
