package daemon

import (
	"fmt"
	"strings"
	"syscall"

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

func isNotRunning(err error) bool {
	var nre *containerNotRunningError
	return errors.As(err, &nre)
}

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

type containerNotRunningError struct {
	error
}

func (e containerNotRunningError) Conflict() {}

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)
}

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 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
}
