# "build" command
#
# Copyright (C) 2014, 2015  Patrick McDermott
#
# This file is part of the ProteanOS Development Kit.
#
# The ProteanOS Development Kit is free software: you can redistribute
# it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# The ProteanOS Development Kit is distributed in the hope that it
# will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the ProteanOS Development Kit.  If not, see
# <http://www.gnu.org/licenses/>.

cmd_build_root=
cmd_build_pkg_dir=
cmd_build_build_deps=

_cmd_build_make_deps_pkg()
{
	local pkg_dir=

	pkg_dir="${cmd_build_root}$(session_dir)/builddeps"
	mkdir -p -- "${pkg_dir}/control" "${pkg_dir}/data"
	printf '2.0\n' >"${pkg_dir}/debian-binary"
	cat >"${pkg_dir}/control/control" <<-EOF
		Package: prokit-builddeps-$(session_id)
		Source: prokit
		Version: 1.0
		Architecture: all
		Platform: all
		Depends: ${cmd_build_build_deps}
		Description: Build dependencies metapackage generated by prokit
		EOF
	(cd -- "${pkg_dir}/data"; tar -czf ../data.tar.gz .)
	(cd -- "${pkg_dir}/control"; tar -czf ../control.tar.gz .)
	(cd -- "${pkg_dir}"; tar -czf ../builddeps.opk \
		'debian-binary' 'data.tar.gz' 'control.tar.gz')
	rm -Rf -- "${pkg_dir}"
}

_cmd_build_fini()
{
	local session_dir=
	local f=

	session_dir="$(session_dir)"

	if [ "x${cmd_build_build_deps}" != 'x' ]; then
		session_exec opkg --autoremove remove \
			prokit-builddeps-$(session_id)
		rm -f -- "${cmd_build_root}${session_dir}/builddeps.opk"
		# Hack to avoid this code branch if the function is called again
		# in response to a signal.
		cmd_build_build_deps=''
	fi

	for f in "${cmd_build_root}${session_dir}/"*; do
		[ -e "${f}" ] || continue
		[ "x${f##*/}" = 'xwd' ] && continue
		mv "${f}" "${cmd_build_pkg_dir}/.."
	done
}

cmd_build_main()
{
	local root=
	local dev=
	local opkbuild_optstring=
	local arch=
	local plat=
	local first_arg=
	local arg=

	if [ ${#} -lt 2 ]; then
		print_cmd_usage 'build' >&2
		return 1
	fi

	root="${1}"
	shift 1

	dev=''
	if is_block "${root}"; then
		dev="${root}"
		if ! root="$(block_mount "${dev}")"; then
			return 2
		fi
	fi

	cmd_build_root="${root}"

	opkbuild_optstring="$(cat -- "${root}/usr/share/opkbuild/optstring")"
	arch="$(cat -- "${root}/etc/proteanos_arch")"
	plat="$(cat -- "${root}/etc/proteanos_plat")"
	while getopts "${opkbuild_optstring}" opt 2>/dev/null; do
		case "${opt}" in
			a) arch="${OPTARG}";;
			p) plat="${OPTARG}";;
		esac
	done

	first_arg=true
	cmd_build_pkg_dir=''
	for arg in "${@}"; do
		if ${first_arg}; then
			set --
			first_arg=false
		else
			set -- "${@}" "${cmd_build_pkg_dir}"
		fi
		cmd_build_pkg_dir="${arg}"
	done

	if ! profile_detect "${root}"; then
		[ "x${dev}" != 'x' ] && block_umount "${root}"
		return 2
	fi

	if ! [ -d "${cmd_build_pkg_dir}" ]; then
		error "$(get_msg 'cmd_build_not_a_dir')" "${cmd_build_pkg_dir}"
		[ "x${dev}" != 'x' ] && block_umount "${root}"
		return 2
	fi
	if ! package_init "${cmd_build_pkg_dir}"; then
		[ "x${dev}" != 'x' ] && block_umount "${root}"
		return 2
	fi
	package_set_substvars "${arch}" "${plat}"

	if ! session_begin "${root}" "${cmd_build_pkg_dir}" _cmd_build_fini \
			false; then
		_cmd_build_fini
		[ "x${dev}" != 'x' ] && block_umount "${root}"
		return 2
	fi

	cmd_build_build_deps="$(package_get_build_deps "${arch}" "${plat}")"
	if [ "x${cmd_build_build_deps}" != 'x' ]; then
		_cmd_build_make_deps_pkg
		session_exec opkg install ../builddeps.opk
	fi

	session_exec opkbuild "${@}"

	_cmd_build_fini

	session_end

	[ "x${dev}" != 'x' ] && block_umount "${root}"

	return 0
}

cmd_build_register()
{
	register_cmd 'build'
}
__init cmd_build_register