#!/bin/sh -eu
#
# Copyright (C) 2022-2025  Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
# All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0-or-later
#

. shell-error

PROG="${0##*/}"
PROG_VERSION=0.2.2

show_usage()
{
	[ -z "$*" ] || message "$*"
	echo "Try \`$PROG --help' for more information." >&2
	exit 1
}

show_help()
{
	cat <<-EOF
	Usage: $PROG [options] --requires <specfile>
	  or:  $PROG [options] --oci-requires <specfile>
	  or:  $PROG [options] --license <specfile>
	  or:  $PROG [options] --build <specfile>

	Options:
	  --target           override target platform;
	  --requires         print the list of required packages;
	  --oci-requires     print required the name of parent OCI image;
	  --license          print license tag from specfile;
	  --build            execute specfile %build section;
	  --sourcedir        path to image source files (defaults to
	                     dirname <specfile>);
	  --workdir          path to working directory (defaults to
	                     ~/img);
	  -v,--version       print program version and exit;
	  -h,--help          show this text and exit.

	Report bugs to https://bugzilla.altlinux.org/

	EOF
	exit
}

print_version()
{
	cat <<-EOF
	$PROG version $PROG_VERSION
	Written by Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>

	Copyright (C) 2022-2025  Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
	This is free software; see the source for copying conditions.  There is NO
	warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	EOF
	exit
}

TEMP=$(getopt -n $PROG -o v,h -l target:,requires,oci-requires,license,build,sourcedir:,workdir:,version,help -- "$@") ||
	show_usage
eval set -- "$TEMP"

target="$(rpm --showrc |sed -ne 's/^install arch[[:space:]]*:[[:space:]]*\([^[:space:]]\+\).*/\1/p')"
export target
sourcedir="$HOME"/in/source
workdir="$HOME"/img
mode=build

while :; do
	case "$1" in
		-h|--help) show_help
			;;
		-v|--version) print_version
			;;
		--target) shift; target="$1" ;;
		--requires) mode=requires ;;
		--oci-requires) mode=oci-requires ;;
		--license) mode=license ;;
		--build) mode=build ;;
		--sourcedir) shift; sourcedir="$1" ;;
		--workdir) shift; workdir="$1" ;;
		--) shift; break
			;;
	esac
	shift
done

[ "$#" -ge 1 ] || show_usage 'Insufficient arguments.'

spec="$1"; shift
if [ -n "${spec##/*}" ]; then
	spec="$PWD/$spec"
fi

check_arch() {
	local exclude="$(sed '/^excludearch:[[:space:]]*/I!d;s///;q' -- "$spec")"
	local exclusive="$(sed '/^exclusivearch:[[:space:]]*/I!d;s///;q' -- "$spec")"

	local arch
	if [ -n "$exclude" ]; then
		for a in $exclude; do
			[ "$a" = "$target" ] || continue
			echo "error: Architecture is excluded: $target" >&2
			exit 1
		done
	fi
	if [ -n "$exclusive" ]; then
		for a in $exclusive; do
			[ "$a" != "$target" ] || return 0
		done
		echo "error: Architecture is not included: $target" >&2
		exit 1
	fi
}
check_arch

license="$(sed '/^license:[[:space:]]*/I!d;s///' -- "$spec")"
[ -n "$license" ] ||
	fatal 'license tag is not set'

if [ -n "${sourcedir##/*}" ]; then
	sourcedir="$PWD/$sourcedir"
fi

if [ -z "$sourcedir" ]; then
	sourcedir="${spec%/*}"
fi

tmpdir=
cleanup_tmpdir()
{
	[ -z "$tmpdir" ] || rm -rf -- "$tmpdir"
	exit "$@"
}

tmpdir=$(mktemp -dt "${0##*/}.XXXXXXXX")
trap 'cleanup_tmpdir $?' EXIT
trap 'exit 143' HUP INT QUIT PIPE TERM

setup_workdir()
{
	local workdir="$1"; shift

	[ "$workdir" != "$sourcedir" ] ||
		continue

	rm -rf "$workdir"
	mkdir -p "$workdir"
	cd "$workdir"

	for f in "$sourcedir"/*; do
		fname="${f##*/}"
		case "$f" in
			*.tar|*.tar.*)
				tar -x --strip-components=1 -f "$f"
				;;
			*)
				cp -a --target-directory . -- "$f"
		esac
	done
}

case "$mode" in
	requires)
		sed '/^buildrequires:[[:space:]]*/I!d;s///' -- "$spec" |
			tr ' ' '\n' | grep . || [ "$?" = 1 ]
		;;
	oci-requires)
		workdir="$tmpdir"/work
		setup_workdir "$workdir"
		cd "$workdir"
		sed '/^from[[:space:]]*/I!d;s///;q' -- Dockerfile
		;;
	license)
		echo "$license"
		;;
	build)
		outdir="$HOME"/out
		mkdir -p "$outdir"

		setup_workdir "$workdir"

		script="$tmpdir"/script
		awk 'start && /^%/ {start=0} start {print $0} /^%build/ {start=1}' "$spec" \
			>"$script"

		sh -ex "$script"
esac
