#!/usr/bin/env bash
# Copyright 1999-2023 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1

option_r=
if ___eapi_has_dosym_r && [[ ${1} == -r ]]; then
	option_r=t
	shift
fi

if [[ $# -ne 2 ]] ; then
	__helpers_die "${0##*/}: two arguments needed"
	exit 1
fi

if ! ___eapi_has_prefix_variables; then
	ED=${D}
fi

if [[ ${2} == */ ]] || [[ -d ${ED%/}/${2#/} && ! -L ${ED%/}/${2#/} ]] ; then
	# implicit basename not allowed by PMS (bug #379899)
	__helpers_die "${0##*/}: dosym target omits basename: '${2}'"
fi

target=${1}

if [[ ${option_r} ]]; then
	# Transparent bash-only replacement for GNU "realpath -m -s".
	# Resolve references to "/./", "/../" and remove extra "/" characters
	# from <path>, without touching any actual file.
	dosym_canonicalize() {
		local path slash i prev out IFS=/

		read -r -d '' -a path < <(printf '%s\0' "${1}")
		[[ ${1} == /* ]] && slash=/

		while true; do
			# Find first instance of non-".." path component followed by "..",
			# or as a special case, "/.." at the beginning of the path.
			# Also drop empty and "." path components as we go along.
			prev=
			for i in "${!path[@]}"; do
				if [[ -z ${path[i]} || ${path[i]} == . ]]; then
					unset "path[i]"
				elif [[ ${path[i]} != .. ]]; then
					prev=${i}
				elif [[ ${prev} || ${slash} ]]; then
					# Found, remove path components and reiterate
					[[ ${prev} ]] && unset "path[prev]"
					unset "path[i]"
					continue 2
				fi
			done
			# No (further) instance found, so we're done
			break
		done

		out="${slash}${path[*]}"
		printf "%s\n" "${out:-.}"
	}

	# Expansion makes sense only for an absolute target path
	[[ ${target} == /* ]] || __helpers_die \
		"${0##*/}: -r specified but no absolute target path: '${target}'"

	target=$(dosym_canonicalize "${target}")
	linkdir=$(dosym_canonicalize "/${2#/}")
	linkdir=${linkdir%/*}	# poor man's dirname(1)
	linkdir=${linkdir:-/}	# always keep the initial "/"

	IFS=/
	for comp in ${linkdir}; do
		if [[ ${target%%/*} == "${comp}" ]]; then
			target=${target#"${comp}"}
			target=${target#/}
		else
			target=..${target:+/}${target}
		fi
	done
	unset IFS
	target=${target:-.}
fi

destdir=${2%/*}
[[ ! -d ${ED%/}/${destdir#/} ]] && dodir "${destdir}"
ln -snf "${target}" "${ED%/}/${2#/}"

ret=${?}
[[ ${ret} -ne 0 ]] && __helpers_die "${0##*/} failed"
exit ${ret}
