package daemon // import "github.com/docker/docker/daemon"

import (
	"fmt"
	"strings"
	"syscall"

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

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

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

type objNotFoundError struct {
	object string
	id     string
}

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

func (e objNotFoundError) NotFound() {}

func errContainerIsRestarting(containerID string) error {
	cause := errors.Errorf("Container %s is restarting, wait until the container is running", containerID)
	return errdefs.Conflict(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 errdefs.Conflict(cause)
}

func errNotPaused(id string) error {
	cause := errors.Errorf("Container %s is already paused", id)
	return errdefs.Conflict(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 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 invalidIdentifier string

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

func (invalidIdentifier) InvalidParameter() {}

type incompatibleDeviceRequest struct {
	driver string
	caps   [][]string
}

func (i incompatibleDeviceRequest) Error() string {
	return fmt.Sprintf("could not select device driver %q with capabilities: %v", i.driver, i.caps)
}

func (incompatibleDeviceRequest) 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 startInvalidConfigError string

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

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

// exitStatus is the exit-code as set by setExitCodeFromError
type exitStatus = int

const (
	exitEaccess     exitStatus = 126 // container cmd can't be invoked (permission denied)
	exitCmdNotFound exitStatus = 127 // container cmd not found/does not exist or invalid bind-mount
	exitUnknown     exitStatus = 128 // unknown error
)

// setExitCodeFromError converts the error returned by containerd
// when starting a container, and applies the corresponding exitStatus to the
// container. It returns an errdefs error (either errdefs.ErrInvalidParameter
// or errdefs.ErrUnknown).
func setExitCodeFromError(setExitCode func(exitStatus), err error) error {
	if err == nil {
		return nil
	}
	errDesc := status.Convert(err).Message()
	contains := func(s1, s2 string) bool {
		return strings.Contains(strings.ToLower(s1), s2)
	}

	// set to 126 for container cmd can't be invoked errors
	if contains(errDesc, syscall.EACCES.Error()) {
		setExitCode(exitEaccess)
		return startInvalidConfigError(errDesc)
	}

	// Go 1.20 changed the error for attempting to execute a directory from
	// syscall.EACCESS to syscall.EISDIR. Unfortunately docker/cli checks
	// whether the error message contains syscall.EACCESS.Error() to
	// determine whether to exit with code 126 or 125, so we have little
	// choice but to fudge the error string.
	if contains(errDesc, syscall.EISDIR.Error()) {
		errDesc += ": " + syscall.EACCES.Error()
		setExitCode(exitEaccess)
		return 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(exitCmdNotFound)
		return startInvalidConfigError(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 isInvalidCommand(errDesc) {
		setExitCode(exitCmdNotFound)
		return startInvalidConfigError(errDesc)
	}

	// TODO: it would be nice to get some better errors from containerd so we can return better errors here
	setExitCode(exitUnknown)
	return errdefs.Unknown(errors.New(errDesc))
}

// isInvalidCommand tries to detect if the reason the container failed to start
// was due to an invalid command for the container (command not found, or not
// a valid executable).
func isInvalidCommand(errMessage string) bool {
	errMessage = strings.ToLower(errMessage)
	errMessages := []string{
		"executable file not found",
		"no such file or directory",
		"system cannot find the file specified",
		"failed to run runc create/exec call",
	}

	for _, msg := range errMessages {
		if strings.Contains(errMessage, msg) {
			return true
		}
	}
	return false
}
