# Contributor: Jakub Jirutka <jakub@jirutka.cz>
# Maintainer: Jakub Jirutka <jakub@jirutka.cz>
# TODO: Add rest of the tools.
# TODO: Fix some scripts/tools to not require bash.
# TODO: Use system-provided gtest library for testing.
pkgname=elektra
_pkgname=libelektra
pkgver=0.8.21
pkgrel=9
pkgdesc="A universal and secure framework to access configuration parameters"
url="https://www.libelektra.org"
arch="all !armhf" # armhf blocked by qt5-qtdeclarative
license="BSD-3-Clause"
_luaver=5.3
# kdb doesn't work correctly without these plugins.
depends="$pkgname-dump=$pkgver-r$pkgrel
	$pkgname-list=$pkgver-r$pkgrel
	$pkgname-spec=$pkgver-r$pkgrel
	$pkgname-sync=$pkgver-r$pkgrel"
checkdepends="bash gnupg ruby-test-unit"
makedepends="
	augeas-dev
	boost-dev
	cmake
	curl-dev
	discount discount-dev
	fts-dev
	libdrm-dev
	libgcrypt-dev
	libgit2-dev
	openssl-dev
	lua$_luaver-dev
	glib-dev
	python3-dev
	qt5-qtbase-dev
	qt5-qtdeclarative-dev
	qt5-qtsvg-dev
	ruby ruby-dev
	swig
	yajl-dev
	yaml-cpp-dev
	"
install="$pkgname.post-deinstall"
triggers="$pkgname.trigger=/usr/lib/$pkgname"
subpackages="
	$pkgname-dev
	$pkgname-doc
	$pkgname-glib
	lua$_luaver-elektra:_lua
	py3-elektra:_py3
	ruby-elektra:_ruby
	$pkgname-qt-gui:_gui
	$pkgname-libs
	$pkgname-bash-completion:bashcomp:noarch
	$pkgname-fish-completion:fishcomp:noarch
	$pkgname-zsh-completion:zshcomp:noarch
	$pkgname-plugins-all:_all:noarch
	"
source="$_pkgname-$pkgver.tar.gz::https://github.com/ElektraInitiative/libelektra/archive/$pkgver.tar.gz
	fix-bash-shebang.patch
	fix-augeas-internal-inconsistency.patch
	cmake-allow-override-rpath.patch
	remove-unneeded-assembly.patch
	"
builddir="$srcdir/$_pkgname-$pkgver"

# All plugins except:
# * status:obsolete
# * status:experimental
# * journald - considered evil
# * wresolver - resolver for non-POSIX, e.g. w32/w64 systems
# * xerces - we don't have xerces package
# * yamlcpp - segfaults FIXME
_plugins="
	augeas
	base64
	boolean
	c
	cachefilter
	camel
	ccode
	conditionals
	constants
	counter
	crypto_gcrypt
	crypto_openssl
	csvstorage
	curlget
	date
	desktop
	dini
	directoryvalue
	dpkg
	dump
	enum
	error
	fcrypt
	filecheck
	fstab
	gitresolver
	glob
	hexcode
	hidden
	hosts
	iconv
	ini
	ipaddr
	keytometa
	line
	lineendings
	list
	logchange
	lua
	mathcheck
	mini
	multifile
	network
	ni
	noresolver
	null
	path
	profile
	range
	regexstore
	rename
	required
	resolver_fm_b_b
	resolver_fm_pb_b
	resolver_fm_hb_b
	resolver_fm_hp_b
	resolver_fm_ub_x
	resolver_fm_xb_x
	resolver_fm_xp_x
	resolver_fm_xhp_x
	resolver_fm_uhb_xb
	resolver_fm_hpu_b
	shell
	spec
	struct
	sync
	syslog
	tcl
	timeofday
	tracer
	type
	uname
	validation
	xmltool
	yajl
	"
for _i in $_plugins; do
	subpackages="$subpackages $pkgname-$_i:_plugin"
done

# All bindings except:
# * status:experimental
# * intercept_env - currently doesn't work on musl (0.8.21)
_bindings="
	cpp
	glib
	swig_lua
	swig_python
	swig_ruby
	"

build() {
	mkdir -p "$builddir"/build
	cd "$builddir"/build

	cmake .. \
		-DCMAKE_BUILD_TYPE=MinSizeRel \
		-DCMAKE_C_FLAGS_MINSIZEREL_INIT="$CFLAGS" \
		-DCMAKE_CXX_FLAGS_MINSIZEREL_INIT="$CXXFLAGS" \
		-DCMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT="$LDFLAGS" \
		-DCMAKE_INSTALL_PREFIX=/usr \
		-DCMAKE_INSTALL_RPATH=/usr/lib/$pkgname \
		-DTARGET_PLUGIN_FOLDER=$pkgname \
		-DCMAKE_VERBOSE_MAKEFILE=OFF \
		-DBUILD_DOCUMENTATION=OFF \
		-DBUILD_SHARED_LIBS=ON \
		-DBUILD_STATIC=OFF \
		\
		-DENABLE_DEBUG=OFF \
		-DENABLE_LOGGER=OFF \
		-DINSTALL_TESTING=OFF \
		-DBINDINGS="$(printf '%s;' $_bindings)" \
		-DPLUGINS="$(printf '%s;' $_plugins)" \
		-DTOOLS='kdb;qt-gui' \
		\
		-DLUA_LIBRARIES="/usr/lib/liblua-$_luaver.so.0" \
		-DLUA_INCLUDE_DIR="$(pkg-config --variable=includedir lua$_luaver )" \
		-DTARGET_LUA_CMOD_FOLDER="$(pkg-config --variable=INSTALL_LMOD lua$_luaver)" \
		-DTARGET_LUA_CMOD_FOLDER="$(pkg-config --variable=INSTALL_CMOD lua$_luaver)"
	make
}

check() {
	cd "$builddir"/build

	# Run tests that doesn't need to write into /etc.
	# FIXME: Allow tests to fail for now.
	make run_nokdbtests || true
}

package() {
	# These are virtual providers. abuild doesn't recognize them as
	# produced by this APKBUILD and tries to install them as make
	# dependencies. That's why they are defined in package().
	depends="$depends $pkgname-resolver"

	cd "$builddir"/build

	make DESTDIR="$pkgdir" install

	# This is a shell script that just executes /usr/lib/elektra/tool_exec/qt-gui.
	# It was originally made as a workaround for some RPATH issue we don't have.
	rm "$pkgdir"/usr/bin/elektra-qt-editor

	cd "$pkgdir"/usr/lib/elektra

	# We create these symlinks in trigger, so they are correctly updated
	# when user install a different provider.
	rm libelektra-resolver.so libelektra-storage.so

	## Delete some useless or unusable tools.

	# Completions are in separate packages.
	rm tool_exec/install-sh-completion
	# This seems to be just for development.
	rm tool_exec/benchmark-createtree
	rm tool_exec/update-snippet-repository
	# Needs experimental plugin mozprefs.
	rm tool_exec/configure-firefox
	# Needs binding intercept_env.
	rm tool_exec/elektrify-getenv
	# Needs experimental binding intercept_fs.
	rm tool_exec/elektrify-open
}

libs() {
	default_libs
	mv "$pkgdir"/usr/lib/*.so.* "$subpkgdir"/usr/lib/
}

glib() {
	pkgdesc="Glib bindings for Elektra"
	depends=""

	_submv usr/lib/libgelektra-*.so
}

_lua() {
	pkgdesc="Lua $_luaver bindings for Elektra"
	depends=""

	_submv usr/lib/lua
}

_py3() {
	pkgdesc="Python 3 bindings for Elektra"
	depends=""

	_submv usr/lib/python3.*
}

_ruby() {
	pkgdesc="Ruby bindings for Elektra"
	depends=""

	_submv usr/lib/ruby
}

_gui() {
	pkgdesc="Qt GUI for Elektra"
	depends="$depends $pkgname-resolver"

	_submv usr/lib/elektra/tool_exec/qt-gui usr/bin/elektra-qt-editor
	_submv usr/share/appdata
	_submv usr/share/applications
	_submv usr/share/icons
}

bashcomp() {
	pkgdesc="Bash completions for $pkgname"
	depends=""
	install_if="$pkgname=$pkgver-r$pkgrel bash-completion"

	_submv usr/share/bash-completion
}

fishcomp() {
	pkgdesc="Fish completions for $pkgname"
	depends=""
	install_if="$pkgname=$pkgver-r$pkgrel fish"

	_submv usr/share/fish/vendor_completions.d usr/share/fish/completions
}

zshcomp() {
	pkgdesc="ZSH completions for $pkgname"
	depends=""
	install_if="$pkgname=$pkgver-r$pkgrel zsh"

	_submv usr/share/zsh/vendor-completions usr/share/zsh/site-functions
}

_plugin() {
	local name=${subpkgname#$pkgname-}
	local readme="$builddir/src/plugins/${name%%_*}/README.md"

	[ -f "$readme" ] || die "$readme doesn't exist!"

	pkgdesc="Elektra plugin - $(_getinfo description "$readme")"
	depends=$(_to_pkgnames "$(_getinfo needs \"$readme\" '')" | xargs)

	if provides=$(_getinfo provides "$readme"); then
		# Convert plugin names to package names.
		provides=$(_to_pkgnames $provides)

		# Remove pkgnames clashing with subpackages.
		: "${_plugins_pkgname:=$(printf \"$pkgname-%s\\n\" $_plugins dev doc libs)}"
		provides=$(_set_difference "$provides" "$_plugins_pkgname" | xargs)
	fi

	# Overrides
	case "$name" in
		base64)
			provider_priority=50;;  # provides binary
		crypto_gcrypt)
			depends="$depends gnupg"
			provider_priority=50;;  # provides crypto
		crypto_*)
			depends="$depends gnupg";;
		dini)
			depends="$depends $pkgname-dump $pkgname-ini"
			provider_priority=40;;  # provides storage storage-ini
		dump)
			provider_priority=50;;  # provides storage
		hexcode)
			provider_priority=50;;  # provides code
		resolver_fm_hpu_b)
			provider_priority=50;;  # provides resolver
	esac
	msg "Resolved provides: $provides"
	msg "Resolved depends: $depends"

	_submv usr/lib/elektra/libelektra-$name.so*
}

_all() {
	pkgdesc="Virtual package that installs *all* plugins shipped with Elektra"
	depends=$(printf "$pkgname-%s=$pkgver-r$pkgrel\n" $_plugins)

	mkdir -p "$subpkgdir"
}

# Prints value of property $1 in the plugin's readme file $2,
# or prints $3 if no value.
_getinfo() {
	local name="$1"
	local file="$2"
	local default="${3:-}"
	local value

	value=$(sed -n "s|^- infos/$name = *\(.*\) *|\1|p" "$file")
	[ "$value$default" ]
	printf '%s\n' "${value:-$default}"
}

# Converts plugin names $@ into package names, i.e. adds prefix $pkgname-
# and replaces "/" with "-".
_to_pkgnames() {
	local item; for item in "$@"; do
		case "$item" in
			*/*) echo "$pkgname-${item%%/*}"
			     echo "$pkgname-$item" | tr '/' '-';;
			*) echo "$pkgname-$item";;
		esac
	done
}

# Prints space-separated items from $1 that are not in $2.
_set_difference() {
	printf '%s\n' $1 $2 $2 | sort | uniq -u
}

# Moves file/directory $1 from the $pkgdir to $2 (or $1 if $2 not given)
# in the $subpkgdir.
_submv() {
	local src="$1"
	local dest="${2:-}"

	if [ "$dest" ]; then
		mkdir -p "$subpkgdir"/${dest%/*}
		mv "$pkgdir"/$src "$subpkgdir"/$dest
	else
		mkdir -p "$subpkgdir"/${src%/*}
		mv "$pkgdir"/$src "$subpkgdir"/${src%/*}/
	fi
	rmdir -p "$pkgdir"/${src%/*} 2>/dev/null || true
}

sha512sums="9ad3bb7eeb36d921189d93cb347ec73262503d85397b574ef603080cee52d1959752740e5018a0e7eb5dc187bce8aae3b6fc0057a6385bce94e5338604c6bc57  libelektra-0.8.21.tar.gz
cbfe8b96a806825d5f7194734a646bdb3fb273bf6be44b3b47e9b2f63bf90a7ece867e74808da743ff33211abba0682aba55d02a3dbfa0a5efc3dc821444bd87  fix-bash-shebang.patch
48d645142bf63282e13d1c76c1ddedc5633e365a1a87d0cd49c75fa801eed44b57fb66eee49badc7a9e6210f6ccd2af82779f0658f90263fd23b959f4e70b84c  fix-augeas-internal-inconsistency.patch
717b343b6509d14949a154bbbf13d5722f47f97717dbd839763fc89f8f9033d5214f903df23b4ca7f196ae9dbfe6a3348542411c714e471ca4a50b39bdff3abc  cmake-allow-override-rpath.patch
9ca27100c7b9e3b64146a4733e7007c6175ba475415cf7523315d21ba8fcfff65e3769ee2e9d59cdf2eb943a5c49786c4811e4deec6c694964da7e0e5292c1f9  remove-unneeded-assembly.patch"
