# Copyright 1999-2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8
NEED_EMACS="27.2"

inherit elisp-common
# inherit elisp-slotted

DESCRIPTION="Convert string regexp to rx notation"
HOMEPAGE="https://elpa.gnu.org/packages/xr.html"
# No sources fetched here; sources come from a separate src-elisp/* package.
SRC_URI=""

LICENSE="GPL-3+"
KEYWORDS="amd64 ~x86"
IUSE="test"
DOCS="README"

# Split PV into:
#   MY_PV = everything before EMACS_V (without the separating dot)
#   EMACS_V = either last 2 components (regular) or last 3 components (vcs, ends in .9999)
#
# Rules:
#   PV=1.2.5.30.3        => MY_PV=1.2.5     EMACS_V=30.3
#   PV=1.25.30.3         => MY_PV=1.25      EMACS_V=30.3
#   PV=1.25.30.0.9999    => MY_PV=1.25      EMACS_V=30.0.9999
#   PV=1.25.30.2.9999    => MY_PV=1.25      EMACS_V=30.2.9999
#
# Errors if PV does not have enough dot components.

split_pv_emacs() {
	local pv=${1:?}
	local -a a my em
	local i emacs_n=2

	IFS=. read -r -a a <<<"${pv}"
	((${#a[@]} >= 3)) || { eerror "PV too short: ${pv}"; return 1; }

	if [[ ${a[-1]} == 9999 ]]; then
		((${#a[@]} >= 4)) || { eerror "PV too short for vcs EMACS_V: ${pv}"; return 1; }
		emacs_n=3
		EMACS="/usr/bin/emacs-${a[-3]}-vcs"
	else
		EMACS="/usr/bin/emacs-${a[-2]}"
	fi

	for (( i=0; i<${#a[@]}-emacs_n; ++i )); do my+=( "${a[i]}" ); done
	for (( i=${#a[@]}-emacs_n; i<${#a[@]}; ++i )); do em+=( "${a[i]}" ); done

	((${#my[@]} >= 1)) || { eerror "Missing MY_PV part in PV: ${pv}"; return 1; }

	MY_PV=$(IFS=.; echo "${my[*]}")
	EMACS_V=$(IFS=.; echo "${em[*]}")
	export MY_PV EMACS_V
	export EMACS
}

set_my_pv_emacs_v() {
	split_pv_emacs "${PV}" || die "Cannot split PV=${PV} into MY_PV and EMACS_V"
}

set_my_pv_emacs_v
SLOT="${EMACS_V}"

RDEPEND="
	=app-editors/emacs-${EMACS_V}*
	=src-elisp/${PN}-${MY_PV}[test?]
"
DEPEND="
	${RDEPEND}
"

S="${WORKDIR}"

# Where the sources live (installed by src-elisp/${PN}-${MY_PV})
export SRC_SITE_LISP_DIR="${SITELISP}/${PN}-${MY_PV}"

# We may redefine SITELISP now
export SITELISP="${SITELISP}.${EMACS_V}"
# Where compiled output should go for this Emacs slot
export OUTPUT_DIR="${SITELISP}/${PN}-${MY_PV}"

src_unpack() { :; }

src_prepare() {
	# TODO: Maybe copying everything from SRC_SITE_LISP_DIR
	# should be done in src_unpack?
	# Maybe simply specify SRC_URI as SRC_SITE_LISP_DIR ?

	cp -a "${SRC_SITE_LISP_DIR}"/* . || die "Missing sources in ${SRC_SITE_LISP_DIR}"
	# TODO: better not to copy in the first place
	# but I'm not sure if that would be more complicated to write down
	if ! use test ; then
		rm ${PN}-test.el
	fi
	default
}

src_compile() {
	[[ -x ${EMACS} ]] || die "Expected ${EMACS} (from =app-editors/emacs-${EMACS_V}*)"

	local el_files=( *.el )
	[[ ${#el_files[@]} -gt 0 ]] || die "No .el files found in ${SRC_SITE_LISP_DIR}"
	elisp-compile "${el_files[@]}" || die
}

src_test() {
	${EMACS} -batch -Q -L .                     \
			 -l ${PN}-test.elc                  \
			 -f ert-run-tests-batch-and-exit || die "ERT test(s) failed."
}

src_install() {
	elisp-install ${PN}-${MY_PV} *.elc

	shopt -s nullglob

	for f in ./*.elc; do
		base=${f##*/}
		base=${base%.elc}

		dosym "${SRC_SITE_LISP_DIR}/${base}.el" \
			  "${OUTPUT_DIR}/${base}.el" || die
	done

	shopt -u nullglob

	dodoc ${DOCS}
}

pkg_postinst() {
	elog "Installed compiled Elisp for Emacs slot ${EMACS_V} into:"
	elog "  ${OUTPUT_DIR}"
	elog "Sources are provided by =src-elisp/${PN}-${MY_PV} in:"
	elog "  ${SRC_SITE_LISP_DIR}"
}