#!/usr/bin/env atf-sh

. $(atf_get_srcdir)/test_env.sh
: ${SH=/bin/sh}

lddtree="$SRCDIR"/lddtree.sh
testdata=$(atf_get_srcdir)/testdata

init_tests \
	lddtree_usage \
	lddtree_version \
	lddtree_sh \
	lddtree_sh_list \
	lddtree_sh_all \
	lddtree_sh_debug \
	lddtree_sh_missing_scanelf \
	lddtree_root \
	lddtree_no_auto_root \
	lddtree_no_auto_root_list \
	lddtree_ldso_conf \
	lddtree_ld_musl_path_conf \
	lddtree_rpath_origin_lib

lddtree_usage_body() {
	# usage to stdout, empty stderr
	atf_check -o match:"Usage:" "$SH" "$lddtree" -h
	atf_check -o match:"Usage:" "$SH" "$lddtree" --help
	# usage to stderr, empty stdout
	atf_check -s exit:1 -e match:"Usage:" "$SH" "$lddtree"
}

lddtree_version_body() {
	for arg in -V --version; do
		atf_check -s exit:0 \
			-o match:'lddtree-[0-9]*.[0-9]*' \
			"$SH" "$lddtree" "$arg"
	done
}

# test without -R
lddtree_sh_body() {
	atf_check -s exit:0 \
		-o match:'sh => /bin/sh \(interpreter .*\)' \
		"$SH" "$lddtree" /bin/sh
}

# test without -R, flat output
# should only output lines prefixed with /
lddtree_sh_list_body() {
	for arg in -l --list; do
		atf_check -s exit:0 \
			-o match:'/bin/sh' \
			-o not-match:'\(interpreter .*\)' \
			-o not-match:'^[^/]' \
			"$SH" "$lddtree" "$arg" /bin/sh
	done
}

lddtree_sh_all_body() {
	for arg in -a --all; do
		atf_check -s exit:0 \
			-o match:'/bin/sh' \
			-o match:'\(interpreter .*\)' \
			"$SH" "$lddtree" "$arg" /bin/sh
	done
}

lddtree_sh_debug_body() {
	for arg in -x --debug; do
		atf_check -s exit:0 \
			-o match:'/bin/sh' \
			-o match:'\(interpreter .*\)' \
			-e match:'^\+' \
			"$SH" "$lddtree" "$arg" /bin/sh
	done
}

lddtree_sh_missing_scanelf_body() {
	for tool in scanelf objdump; do
		if PATH=/bin command -v "$tool"; then
			atf_skip "$tool found in /bin"
		fi
	done
	PATH=/bin atf_check -s exit:1 \
		-e match:"needs either scanelf or binutils" \
		"$SH" "$lddtree" /bin/sh
}

lddtree_root_body() {
	cp -rva $(atf_get_srcdir)/testdata/x86_64/* "$PWD" \
		|| atf_fail "failed to copy test data"
	for arg in -R --root; do
		atf_check -s exit:0 \
			-o match:"^hello => $PWD/usr/bin/hello \(interpreter => $PWD/lib/ld-musl-x86_64.so.1\)" \
			-o match:"^    libhello.so.1 => $PWD/usr/lib/libhello.so.1" \
			-o match:"^    libc.musl-x86_64.so.1 => $PWD/lib/libc.musl-x86_64.so.1" \
			"$SH" "$lddtree" "$arg" "$PWD"/ /usr/bin/hello
	done
}

lddtree_no_auto_root_body() {
	cp -rva "$testdata"/x86_64/* "$PWD" \
		|| atf_fail "failed to copy test data"
	atf_check -s exit:0 \
		-o match:"^hello => $PWD/usr/bin/hello \(interpreter => $PWD/lib/ld-musl-x86_64.so.1\)" \
		-o match:"^    libhello.so.1 => $PWD/usr/lib/libhello.so.1" \
		-o match:"^    libc.musl-x86_64.so.1 => $PWD/lib/libc.musl-x86_64.so.1" \
		"$SH" "$lddtree" --no-auto-root --root "$PWD"/ "$PWD/usr/bin/hello"
}

lddtree_no_auto_root_list_body() {
	cp -rva "$testdata"/x86_64/* "$PWD" \
		|| atf_fail "failed to copy test data"
	atf_check -s exit:0 \
		-o match:"/lib/ld-musl-x86_64.so.1" \
		-o match:"/lib/libc.musl-x86_64.so.1" \
		-o match:"/usr/bin/hello" \
		-o match:"/usr/lib/libhello.so.1" \
		-o match:"/usr/lib/libhello.so.1.0" \
		-o not-match:"gnu" \
		-o not-match:"ld-linux-x86-64.so.2" \
		"$SH" "$lddtree" --list --no-auto-root --root "$PWD"/ "$PWD/usr/bin/hello"
}

lddtree_ldso_conf_body() {
	cp -rva "$testdata"/x86_64/* "$PWD" \
		|| atf_fail "failed to copy test data"
	mkdir etc
	echo "/usr/gnu/lib" > etc/ld.so.conf
	atf_check -s exit:0 \
		-o match:"/usr/gnu/bin/hello" \
		-o match:"/usr/gnu/lib/libhello.so.1" \
		-o match:"/lib64/ld-linux-x86-64.so.2" \
		-o match:"/lib/x86_64-linux-gnu/libc.so.6" \
		-o not-match:"musl" \
		-o not-match:"/usr/lib/libhello.so.1" \
		"$SH" "$lddtree" --list --no-auto-root --root "$PWD"/ "$PWD/usr/gnu/bin/hello"
}

lddtree_ld_musl_path_conf_body() {
	cp -rva "$testdata"/x86_64/* "$PWD" \
		|| atf_fail "failed to copy test data"
	mkdir etc usr/musl
	mv usr/lib usr/musl/
	echo "/usr/musl/lib" > etc/ld-musl-x86_64.path
	atf_check -s exit:0 \
		-o match:"/usr/bin/hello" \
		-o match:"/usr/musl/lib/libhello.so.1" \
		-o match:"/lib/ld-musl-x86_64.so.1" \
		-o match:"/lib/libc.musl-x86_64.so.1" \
		-o not-match:"ld-linux-x86-64.so.2" \
		-o not-match:"gnu" \
		"$SH" "$lddtree" --list --no-auto-root --root "$PWD"/ "$PWD/usr/bin/hello"
}

lddtree_rpath_origin_lib_body() {
	cp -rva "$testdata"/x86_64/* "$PWD" \
		|| atf_fail "failed to copy test data"
	mkdir etc usr/musl
	mv -v usr/lib usr/bin usr/musl/
	for bin in hello-rpath-origin-lib hello-rpath-origin-lib2; do
		atf_check -s exit:0 \
			-o match:"/usr/musl/bin/hello" \
			-o match:"/usr/musl/lib/libhello.so.1" \
			-o match:"/lib/ld-musl-x86_64.so.1" \
			-o match:"/lib/libc.musl-x86_64.so.1" \
			-o not-match:"ld-linux-x86-64.so.2" \
			-o not-match:"gnu" \
			"$SH" "$lddtree" --list --no-auto-root --root "$PWD"/ "$PWD/usr/musl/bin/$bin"
	done
}


