#! /usr/bin/env bash

cmd_dir="$(dirname "$0")" || panic

panic()
{
	echo "ERROR: $@"
	exit 1
}

warn()
{
	echo "WARNING: $@"
}

tag_to_version()
{
	local tag="$1"
	pattern='^v[0-9]+\.[0-9]+\.[0-9]+.*$'
	local version
	if [[ "$tag" =~ $pattern ]]; then
		version="${tag:1}"
	else
		version="$tag"
	fi
	echo "$version" || return 1
}

usage()
{
	echo "bad usage: $@"
	exit 2
}

tmp_dir=
workspace_dir=
out_dir=
github_ref=

while getopts t:w:o:r: opt; do
	case "$opt" in
	w)
		workspace_dir="$OPTARG";;
	t)
		tmp_dir="$OPTARG";;
	o)
		out_dir="$OPTARG";;
	r)
		github_ref="$OPTARG";;
	\?)
		usage "invalid option $opt"
		break;;
	esac
done
shift $((OPTIND - 1))

if [ -z "$github_ref" ]; then
	usage "no GitHub ref specified"
fi
if [ -z "$out_dir" ]; then
	usage "no output directory specified"
fi
if [ -z "$workspace_dir" ]; then
	usage "no workspace directory specified"
fi
if [ -z "$tmp_dir" ]; then
	usage "no temporary directory specified"
fi

# Ensure an absolute pathname.
workspace_dir="$(readlink -f "$workspace_dir")" || \
  panic "cannot get absolute pathname"

if [ ! -d "$workspace_dir" ]; then
	panic "no such directory $workspace_dir"
fi

echo "temporary directory: $tmp_dir"
echo "workspace directory: $workspace_dir"
echo "GitHub ref: $github_ref"

commit="$(git -C "$workspace_dir" rev-parse HEAD)" || \
  panic "cannot get commit"
tag="$(awk -v FS="/" '{print $3;}' <<< "$github_ref")" || \
  panic "cannot get tag"
version="$(tag_to_version "$tag")" || \
  panic "cannot get version"
name="xv-3.10a-js-$version"

source_dir="$tmp_dir/$name"
build_dir="$tmp_dir/build"
install_dir="$tmp_dir/install"
news_file="$workspace_dir/NEWS.txt"
changelog_file="$source_dir/ChangeLog"
release_notes_file="$out_dir/release_notes.txt"
archive_file="$out_dir/${name}.tar.gz"

echo "name: $name"
echo "commit: $commit"
echo "tag: $tag"
echo "version: $version"

for dir in "$tmp_dir" "$out_dir" "$build_dir" "$source_dir" "$install_dir"; do
	if [ ! -d "$dir" ]; then
		mkdir -p "$dir" || panic "cannot make directory $dir"
	fi
done

cp -a "$workspace_dir/." "$source_dir" || \
  panic "cannot copy"
rm -rf "$source_dir/.git" || \
  panic "cannot remove .git directory"

git -C "$workspace_dir" log --stat -M -C --name-status --no-color | \
  fmt --split-only > "$changelog_file" || \
  panic "cannot generate changelog"

"$cmd_dir"/extract_release_notes < "$news_file" > "$release_notes_file" || \
  panic

cmake \
  -G "Unix Makefiles" \
  -DCMAKE_INSTALL_PREFIX="$install_dir" \
  -H"$source_dir" -B"$build_dir" || \
  panic "cmake failed"

cmake --build "$build_dir" --clean-first || \
  panic "make clean/all failed"

cmake --build "$build_dir" --target install || \
  panic "make install failed"

remove_list=()

remove_list+=(.gitattributes)
remove_list+=(.gitignore)
remove_list+=(.github)
remove_list+=(build/github)

for file in "${remove_list[@]}"; do
	if [ ! -e "$source_dir/$file" ]; then
		warn "missing file/directory $file"
	fi
	rm -rf "$source_dir/$file" || \
	  panic "cannot remove file/directory $file"
done

tar -C "$tmp_dir" -czf - "$name" > "$archive_file" || \
  panic "cannot make archive"
