#! /usr/bin/bash

#  This script is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License version 2 as
#  published by the Free Software Foundation.
#
#  See the COPYING and AUTHORS files for more details.

# Read in library functions
if [ "$(type -t patch_file_name)" != function ]
then
	if ! [ -r $QUILT_DIR/scripts/patchfns ]
	then
		echo "Cannot read library $QUILT_DIR/scripts/patchfns" >&2
		exit 1
	fi
	. $QUILT_DIR/scripts/patchfns
	if [ -n "$SUBDIR" ]
	then
		# Damn, found an enclosing quilt directory; don't follow its settings
		cd $SUBDIR
		unset SUBDIR
		unset QUILT_PC QUILT_PATCHES QUILT_SERIES
		: ${QUILT_PC:=.pc}
		: ${QUILT_PATCHES:=patches}
		: ${QUILT_SERIES:=series}
	fi
fi

check_for_existing_directories()
{
	local tag dir last_dir arg status=0

	while read tag dir arg
	do
		[ "$dir" != "." -a "$dir" != "$last_dir" ] || continue

		if [ -e "$prefix$dir" ]
		then
			printf $"Directory %s exists\n" \
			       "$prefix$dir" >&2
			status=1
		fi
		last_dir=$dir
	done < $tmpfile

	return $status
}

check_for_existing_files()
{
	local tag dir last_dir arg status=0

	while read tag dir arg
	do
		[ "$tag" = "patch" -a "$dir" != "$last_dir" ] || continue

		if [ -e "$prefix$dir/$QUILT_PATCHES" ]
		then
			printf $"Directory %s exists\n" \
			       "$prefix$dir/$QUILT_PATCHES" >&2
			status=1
		fi
		if [ -e "$prefix$dir/$QUILT_SERIES" ]
		then
			printf $"File %s exists\n" \
			       "$prefix$dir/$QUILT_SERIES" >&2
			status=1
		fi
		last_dir=$dir
	done < $tmpfile

	return $status
}

create_symlink()
{
	local target=$1 link=$2 up
	if [ "${target:0:1}" = / -o "${link:0:1}" = / ]
	then
		ln -s "$target" "$link"
		return
	fi

	set -- "$(echo "$PWD/$target" | \
		  sed -r -e 's://:/:g' \
			 -e ':again' \
			 -e 's:/[^/]+/\.\.(/|$):\1:g' \
			 -e 'tagain')" \
	       "$(echo "$PWD/$link" | \
		  sed -r -e 's://:/:g' \
			 -e ':again' \
			 -e 's:/[^/]+/\.\.(/|$):\1:g' \
			 -e 'tagain')"
	while [ "${1%%/*}" = "${2%%/*}" ]
	do
		set -- "${1#*/}" "${2#*/}"
	done
	up=$(echo "${2%/*}" | sed -re 's:[^/]+:..:g')
	set -- "${up:+$up/}$1"
	set -- "${1%/}"
	ln -s "${1:-.}" "$link"
}

usage()
{
	printf $"Usage: quilt setup [-d path-prefix] [-v] [--sourcedir dir] [--fuzz=N] {specfile|seriesfile}\n"
	if [ x$1 = x-h ]
	then
		printf $"
Initializes a source tree from an rpm spec file or a quilt series file.

-d	Optional path prefix for the resulting source tree.

--sourcedir
	Directory that contains the package sources. Defaults to \`.'.

-v	Verbose debug output.

--fuzz=N
	Set the maximum fuzz factor (needs rpm 4.6 or later).
"
		exit 0
	else
		exit 1
	fi
}

options=`getopt -o d:vh --long sourcedir:,fuzz: -- "$@"`

if [ $? -ne 0 ]
then
	usage
fi

eval set -- "$options"

prefix=
sourcedir=

while true
do
	case "$1" in
	-d)
		prefix=${2%/}/
		shift 2 ;;
	-h)
		usage -h ;;
	-v)
		verbose=-v
		shift ;;
	--sourcedir)
		sourcedir=${2%/}/
		shift 2 ;;
	--fuzz)
		opt_fuzz="--fuzz $2"
		shift 2 ;;
	--)
		shift
		break ;;
	esac
done

if [ $# -ne 1 ]
then
	usage
fi

[ -n "$sourcedir" ] && opt_sourcedir="--sourcedir $sourcedir"

tmpfile=$(gen_tempfile)
add_exit_handler "rm -f $tmpfile"

case "$1" in
*.spec)
	spec_file=$1

	if ! $QUILT_DIR/scripts/inspect $verbose $opt_sourcedir $opt_fuzz \
					"$spec_file" 2>&1 > $tmpfile
	then
		printf $"The %%prep section of %s failed; results may be incomplete\n" "$spec_file"
		if [ -z "$verbose" ]
		then
			printf $"The -v option will show rpm's output\n"
		fi
	fi
	;;
*)
	series_file=$1
	# parse series file
	while read line; do
		set -- $line
		case "$@" in
		"# Sourcedir: "*)
			shift 2
			tar_dir="$@"
			tar_dir=${tar_dir// /\\ }
			;;
		"# Source: "*)
			shift 2
			source="$@"
			filetype="$(file -b "$source")"
			case "$filetype" in
			Zip*)
				echo "unzip ${tar_dir:-.} ${source// /\\ }"
				;;
			*)
				echo "tar ${tar_dir:-.} ${source// /\\ }"
				;;
			esac
			;;
		"# Patchdir: "*)
			shift 2
			patch_dir="$@"
			patch_dir=${patch_dir// /\\ }
			;;
		''|'#'*)
			;;
		*)
			echo "patch ${patch_dir:-.} $@" ;;
		esac
	done < "$series_file" > $tmpfile
	;;
esac

# Make sure that unpacking will not overwrite anything
check_for_existing_directories || exit 1

while read tag dir arg1 arg2
do
	case "$tag" in
	tar)
		tarball=$sourcedir$arg1
		if [ ! -e "$tarball" ]
		then
			printf $"File %s not found\n" "$tarball" >&2
			exit 1
		fi
		printf $"Unpacking archive %s\n" "$tarball"
		mkdir -p "${prefix:-.}" "$prefix$dir"
		cat_file "$tarball" \
		| tar xf - -C "$prefix$dir"
		;;
	unzip)
		tarball=$sourcedir$arg1
		if [ ! -e "$tarball" ]
		then
			printf $"File %s not found\n" "$tarball" >&2
			exit 1
		fi
		printf $"Unpacking archive %s\n" "$tarball"
		mkdir -p "${prefix:-.}" "$prefix$dir"
		unzip -qqo "$tarball" -d "$prefix$dir"
		;;
	esac
done < $tmpfile

if ! check_for_existing_files
then
	echo $"Trying alternative patches and series names..." >&2
	QUILT_PATCHES=quilt_patches
	QUILT_SERIES=quilt_series
	check_for_existing_files || exit 1
fi

while read tag dir arg1 arg2
do
	case "$tag" in
	tar|unzip)
		tar_dir="$dir"
		[ "$tar_dir" = . ] && tar_dir=
		tar_file="$arg1"
		;;
	patch)
		if [ ! -e "$prefix$dir/$QUILT_PATCHES" ]
		then
			create_symlink "$sourcedir" "$prefix$dir/$QUILT_PATCHES"
			(cd "$prefix$dir" && create_db)
		fi

		if [ -n "$series_file" ]
		then
			[ -e "$prefix$dir/$QUILT_SERIES" ] \
			|| create_symlink "$series_file" \
					  "$prefix$dir/$QUILT_SERIES"
		else
			if ! [ -e "$prefix$dir/$QUILT_SERIES" ]
			then
				(	echo "# Patch series file for quilt," \
					     "created by ${0##*/}"
					[ -n "$tar_dir" ] \
						&& echo "# Sourcedir: $tar_dir"
					[ -n "$tar_file" ] \
						&& echo "# Source: $tar_file"
					echo "# Patchdir: $dir"
					echo "#"
				) > "$prefix$dir/$QUILT_SERIES"
			fi
			echo "$arg1" $arg2 >> "$prefix$dir/$QUILT_SERIES"
		fi
		;;
	esac
done < $tmpfile
### Local Variables:
### mode: shell-script
### End:
# vim:filetype=sh
