# This file is part of shellfire core. It is subject to the licence terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/shellfire-dev/core/master/COPYRIGHT. No part of shellfire core, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
# Copyright © 2014-2015 The developers of shellfire core. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/shellfire-dev/core/master/COPYRIGHT.


core_validate_exit()
{
	local message="$1"
	if [ $code -eq $core_commandLine_exitCode_USAGE ]; then
		core_commandLine_exitBadCommandLine "$message"
	else
		core_exitError $code "$message"
	fi
}

core_validate_pathNotEmpty()
{
	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	if [ -z "$value" ]; then
		core_validate_exit "The $category '$name' specifies a path '$value' which is empty"
	fi
}

core_validate_folderPathReadableAndSearchable()
{
	core_validate_pathNotEmpty "$@"

	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	local messageFragment="The $category '$name' specifies a path '$value' which"
	if [ ! -e "$value" ]; then
		core_validate_exit "$messageFragment does not exist"
	fi
	if [ ! -d "$value" ]; then
		core_validate_exit "$messageFragment is not a directory"
	fi
	if [ ! -r "$value" ]; then
		core_validate_exit "$messageFragment is not a readable directory"
	fi
	if [ ! -x "$value" ]; then
		core_validate_exit "$messageFragment is not a searchable directory"
	fi
}

core_validate_folderPathReadableAndSearchableAndWritable()
{
	core_validate_folderPathReadableAndSearchable "$@"

	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	if [ ! -w "$value" ]; then
		core_validate_exit "The $category '$name' specifies a path '$value' which is not a writable directory"
	fi
}

core_validate_parentFolderPathReadableAndSearchable()
{
	core_validate_pathNotEmpty "$@"

	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"

	if [ "$value" = '/' ]; then
		core_validate_exit "The $category '$name' specifies a path '$value' with no parent"
	fi
	if [ "$(core_compatibility_basename "$value")" = "$value" ]; then
		local parentPath="$(pwd)"/..
	else
		local parentPath="$(core_compatibility_dirname "$value")"
	fi
	
	local messageFragment="The $category '$name' specifies a path '$value' with a parent which"
	if [ ! -e "$parentPath" ]; then
		core_validate_exit "$messageFragment does not exist"
	fi
	if [ ! -d "$parentPath" ]; then
		core_validate_exit "$messageFragment is not a directory"
	fi
	if [ ! -r "$parentPath" ]; then
		core_validate_exit "$messageFragment is not a readable directory"
	fi
	if [ ! -x "$parentPath" ]; then
		core_validate_exit "$messageFragment is not a searchable directory"
	fi
}

core_validate_parentFolderPathReadableAndSearchableAndWritable()
{
	core_validate_parentFolderPathReadableAndSearchable "$@"

	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"

	if [ "$value" = '/' ]; then
		core_validate_exit "The $category '$name' specifies a path '$value' with no parent"
	fi
	if [ "$(core_compatibility_basename "$value")" = "$value" ]; then
		local parentPath="$(pwd)"/..
	else
		local parentPath="$(core_compatibility_dirname "$value")"
	fi
	
	if [ ! -w "$parentPath" ]; then
		core_validate_exit "The $category '$name' specifies a path '$value' with parent which is not a writable directory"
	fi
}

core_validate_folderPathIsReadableAndSearchableAndWritableOrCanBeCreated()
{
	local value="$4"
	
	if [ -d "$value" ]; then
		core_validate_folderPathReadableAndSearchableAndWritable "$@"
	else
		core_validate_parentFolderPathReadableAndSearchableAndWritable "$@"
	fi
}

core_validate_filePathReadable()
{
	core_validate_pathNotEmpty "$@"

	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	local messageFragment="The $category '$name' specifies a path '$value' which"
	if [ ! -e "$value" ]; then
		core_validate_exit "$messageFragment does not exist"
	fi
	if [ ! -f "$value" ]; then
		core_validate_exit "$messageFragment is not a file"
	fi
	if [ ! -r "$value" ]; then
		core_validate_exit "$messageFragment is not a readable file"
	fi
}

core_validate_filePathReadableAndExecutable()
{
	core_validate_filePathReadable "$@"

	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	local messageFragment="The $category '$name' specifies a path '$value' which"
	if [ ! -x "$value" ]; then
		core_validate_exit "$messageFragment is not an executable file"
	fi
}

core_validate_filePathReadableAndExecutableAndNotEmpty()
{
	core_validate_filePathReadableAndExecutable "$@"

	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	if [ ! -s "$value" ]; then
		core_validate_exit "The $category '$name' specifies a path which is an empty file"
	fi
}

core_validate_socketPathReadableAndWritable()
{
	core_validate_pathNotEmpty "$@"

	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	local messageFragment="The $category '$name' specifies a path '$value' which"
	if [ ! -e "$value" ]; then
		core_validate_exit "$messageFragment does not exist"
	fi
	if [ ! -S "$value" ]; then
		core_validate_exit "$messageFragment is not a socket"
	fi
	if [ ! -r "$value" ]; then
		core_validate_exit "$messageFragment is not a readable socket"
	fi
	if [ ! -x "$value" ]; then
		core_validate_exit "$messageFragment is not an executable socket"
	fi
}

core_validate_characterDeviceFileReadableAndWritable()
{
	core_validate_pathNotEmpty "$@"

	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	local messageFragment="The $category '$name' specifies a path '$value' which"
	if [ ! -e "$value" ]; then
		core_validate_exit "$messageFragment does not exist"
	fi
	if [ ! -c "$value" ]; then
		core_validate_exit "$messageFragment is not a character device file"
	fi
	if [ ! -r "$value" ]; then
		core_validate_exit "$messageFragment is not a readable character device file"
	fi
	if [ ! -x "$value" ]; then
		core_validate_exit "$messageFragment is not an executable character device file"
	fi
}

core_validate_isBoolean()
{
	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	set +e
	core_variable_isTrue "$value"
	local exitCode=$?
	set -e
	
	if [ $exitCode -eq 2 ]; then
		core_validate_exit "The $category '$name' should be yes or no, not '$value'"
	fi
}

# From https://stackoverflow.com/questions/806906/how-do-i-test-if-a-variable-is-a-number-in-bash
# See comments by Gilles for negative number tests
core_validate_isUnsignedInteger()
{
	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	case "$value" in
	    ''|*[!0-9]*)
			core_validate_exit "The $category '$name' should be an unsigned integer, not '$value'"
		;;
		
	    *)
			:
		;;
	esac
}

core_validate_nonDynamicPort()
{
	local code=$1
	local category="$2"
	local name="$3"
	local value="$4"
	
	core_validate_isUnsignedInteger $code "$category" "$name" "$value"
	if [ $value -lt 1 ]; then
		core_validate_exit "The $category '$name' should be between 1 and 65535, not '$value'"
	fi
	if [ $value -gt 65535 ]; then
		core_validate_exit "The $category '$name' should be between 1 and 65535, not '$value'"
	fi
}
