# Save file checksums.
# For file with a name "file" it will create a new file called ".file.sha1" with hash in it.
# All files by default.
# Usage: checksum_create [FILES]
function checksum_create() {
	local IFS=$'\n'
	local targets=("${@}")
	local count=0
	local total=${#}
	local failed=0

	# All files by default.
	if [[ "${targets}" = "" ]]; then
		targets=($(ls --classify | grep -v /\$))
		total=${#targets[@]}
	fi

	# Iterate each file.
	for target in "${targets[@]}"; do
		local hashfile=".${target#./}.sha1"

		# Increment count.
		((count++))

		# Status info.
		local status="[${count}/${total}] ${target}"
		echo -e "${status}"

		# Skip if hash exists.
		[[ -f "${hashfile}" ]] && continue

		# Calculate hash.
		pv "${target}" | sha1sum > ${hashfile}

		# Report success.
		if [[ ${?} != 0 ]]; then
			echo -e "${color_bred}${status}: Failed.${color_default}"
			((failed++))
		fi
	done

	if [[ ${failed} != 0 ]]; then
		echo -e "${color_bred}Failed: ${failed}.${color_default}"
		return 1
	fi

	[[ ${total} = 0 ]] && return 1
}

# Check stored values against actual files.
# All files by default.
# Usage: checksum_check [FILES]
function checksum_check() {
	local IFS=$'\n'
	local targets=("${@}")
	local count=0
	local total=${#}
	local failed=0
	local skipped=0

	# All files by default.
	if [[ "${targets}" = "" ]]; then
		targets=($(ls --classify | grep -v /\$))
		total=${#targets[@]}
	fi

	# Iterate each file.
	for target in "${targets[@]}"; do
		local hashfile=".${target#./}.sha1"

		# Increment count.
		((count++))

		# Status info.
		local status="[${count}/${total}] ${target}"
		echo -e "${status}"

		# Skip if hash doesn't exist.
		[[ -f "${hashfile}" ]] || { ((skipped++)); continue; }

		# Calculate hash.
		local stored=$(cat "${hashfile}" | cut -d\	-f1)
		local actual=$(pv "${target}" | sha1sum | cut -d\	-f1)

		if [[ "${stored}" != "${actual}" ]]; then
			echo -e "${color_bred}${status}: Failed.${color_default}"
			((failed++))
		fi
	done

	if [[ ${skipped} != 0 ]]; then
		echo -e "${color_byellow}Skipped: ${skipped}.${color_default}"
		return 1
	fi

	if [[ ${failed} != 0 ]]; then
		echo -e "${color_bred}Failed: ${failed}.${color_default}"
		return 1
	fi
}

# Calculate hashes for all files recursively and store in a file called "checksum.sha1".
function checksum() {
	find -type f | parallel -j $(_core_count) -- sha1sum {} >> checksum.sha1
}

# Create checksum for a file.
# Usage: _checksum_create <FILE>
function _checksum_create() {
	local path="${1%/*}"
	local name="${1##*/}"
	sha1sum "${path}/${name}" > "${path}/.${name}.sha1"
}

# Check checksum for a file.
# Usage: _checksum_check <FILE>
function _checksum_check() {
	local file="${1##*\ \ }"
	local stored="${1%%\ \ *}"

	# Skip if no file.
	[[ -f "${file}" ]] || return 0

	# Check file hash.
	local actual=$(sha1sum "${file}")
	actual="${actual%%\ \ *}"

	# Compare values.
	if [[ "${stored}" != "${actual}" ]]; then
		echo -e "${color_bred}${file}: Failed.${color_default}"
		return 1
	fi

	return 0
}