#!/bin/bash
#
#	Script to reorder files back to sanity
#
# This script requires hxtools, rsync, xz to be installed.

# bash -x is too noisy, so we roll our xrm,xmv,etc.
function xrm
{
	echo "+ rm -Rf $@" >&2;
	rm -Rf "$@";
}

function xmv
{
	local target="${@:(-1)}";
	local l="$((${#target}-1))";

	echo "+ xmv $@" >&2;
	if [[ ! -e "$target" ]] && [[ "${target:l}" == "/" ]]; then
		echo "++ mdp $target" >&2;
		mkdir -p "$target";
	elif [[ ! -d "$target" ]]; then
		echo "++ bmd "$(dirname "$target") >&2;
		mkdir -p $(dirname "$target");
	fi;
	# $@ still contains target
#	mv cannot deal with splicing
#	echo "++ mv $@" >&2;
#	mv "$@" || exit 1;
	echo "++ rsync $@" >&2;
	rsync -HSa --remove-source-files -- "$@" || exit 1;
}

function xrmdir
{
	find "$@" -type d -print0 | sort -rz | xargs -0 rmdir;
}

function xcleanup
{
	xrm {nv270,nv173,nv96,nv71}-{noarch,kernel,x64,x86};
	xrm "$nv270_x64" "$nv270_x86";
	xrm "$nv173_x64" "$nv173_x86";
	xrm "$nv96_x64" "$nv96_x86";
	xrm "$nv71_x64" "$nv71_x86";
}

function libdir
{
	if [[ "$1" == "x64" ]]; then
		echo "lib64";
	else
		echo "lib";
	fi;
}

ver_nv270="270.41.06";
ver_nv173="173.14.28";
ver_nv96="96.43.19";
ver_nv71="71.86.14";
nv270_x64="NVIDIA-Linux-x86_64-$ver_nv270";
nv270_x86="NVIDIA-Linux-x86-$ver_nv270";
nv173_x64="NVIDIA-Linux-x86_64-$ver_nv173-pkg2";
nv173_x86="NVIDIA-Linux-x86-$ver_nv173-pkg1";
nv96_x64="NVIDIA-Linux-x86_64-$ver_nv96-pkg2";
nv96_x86="NVIDIA-Linux-x86-$ver_nv96-pkg1";
nv71_x64="NVIDIA-Linux-x86_64-$ver_nv71-pkg2";
nv71_x86="NVIDIA-Linux-x86-$ver_nv71-pkg1";

trap "exit 1" INT;
xcleanup;

function nv270_list
{
	local dir="$1";
	local arch="$2";
	local lib="$(libdir $arch)";

	xrm "$dir"/*.{a,la};
	xrm "$dir"/tls_test*;
	xrm "$dir"/{NVIDIA_Changelog,README.txt,makeself.sh,mkprecompiled};
	xrm "$dir"/{32,nvidia-installer,pkg-history.txt};
	xrm "$dir"/.manifest;
	xmv "$dir"/html/ nv270-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/LICENSE nv270-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/kernel/ nv270-kernel/;
	xmv "nv270-kernel/nv-kernel.o" "nv270-kernel/nv-kernel_$arch.bin";
	xmv "$dir"/gl*.h nv270-noarch/usr/include/nvidia/GL/;
	xmv "$dir"/libglx.so* "nv270-$arch/usr/$lib/xorg/modules/updates/extensions/";
	xmv "$dir"/*_drv.so "nv270-$arch/usr/$lib/xorg/modules/drivers/";
	xmv "$dir"/libGL.so* "nv270-$arch/usr/X11R6/$lib/";
	xmv "$dir"/lib*.so* "nv270-$arch/usr/$lib/";
	ln -s libcuda.so.1 "nv270-$arch/usr/$lib/libcuda.so"; # libcudart.so wants this
	xmv "$dir"/*.1.gz nv270-noarch/usr/share/man/man1/;
	xmv "$dir"/nvidia-{settings,smi,xconfig} "nv270-$arch/usr/bin/";
	xmv "$dir/nvidia-bug-report.sh" nv270-noarch/usr/bin/;
	xmv "$dir"/*.desktop nv270-noarch/usr/share/applications/;
	xmv "$dir"/nvidia-settings.png nv270-noarch/usr/share/pixmaps/;
	xmv "$dir"/nvidia.icd nv270-noarch/etc/OpenCL/vendors/;
	xmv "$dir"/tls/ "nv270-$arch/usr/$lib/tls/";
}

if [[ -x "$nv270_x64.run" ]] && [[ -x "$nv270_x86.run" ]]; then
	"./$nv270_x64.run" --extract-only;
	"./$nv270_x86.run" --extract-only;

	nv270_list "$nv270_x86" x86;
	nv270_list "$nv270_x64" x64;

	xrmdir "$nv270_x64" "$nv270_x86";
	parts="$parts nv270";
fi;

function nv173_list
{
	local dir="$1";
	local arch="$2";
	local lib="$(libdir $arch)";

	xrm "$dir"/{.manifest,nvidia-installer,pkg-history.txt};
	xrm "$dir/usr/X11R6/lib/libXvMCNVIDIA.a";
	xmv "$dir"/usr/X11R6/lib/libXvMCNVIDIA.so.* "nv173-$arch/usr/X11R6/$lib/";
	xmv "$dir/usr/X11R6/lib/modules/drivers/" "nv173-$arch/usr/$lib/xorg/modules/drivers/";
	xmv "$dir/usr/X11R6/lib/modules/extensions/" "nv173-$arch/usr/$lib/xorg/modules/updates/extensions/";
	xmv "$dir"/usr/X11R6/lib/modules/lib*.so* "nv173-$arch/usr/$lib/";
	xrm "$dir"/usr/bin/{makeself.sh,mkprecompiled};
	xmv "$dir"/usr/bin/nvidia-bug-report.sh nv173-noarch/usr/bin/;
	xmv "$dir"/usr/bin/nvidia-{settings,smi,xconfig} "nv173-$arch"/usr/bin/;
	xrm "$dir"/usr/bin/tls_test*;
	xmv "$dir"/usr/include/* nv173-noarch/usr/include/nvidia/;
	xrm "$dir"/usr/lib/libGL.la;
	xmv "$dir"/usr/lib/libGL*.so.* "nv173-$arch/usr/X11R6/$lib/";
	xmv "$dir"/usr/lib/lib*.so.* "nv173-$arch/usr/$lib/";
	xmv "$dir"/usr/lib/tls/ "nv173-$arch/usr/$lib/tls/";
	xrm "$dir/usr/lib32";
	xmv "$dir"/usr/share/applications/ nv173-noarch/usr/share/applications/;
	xmv "$dir"/usr/share/doc/ nv173-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/LICENSE nv173-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/usr/share/man/ nv173-noarch/usr/share/man/;
	xmv "$dir"/usr/share/pixmaps/ nv173-noarch/usr/share/pixmaps/;
	xmv "$dir"/usr/src/nv/ nv173-kernel/;
	xrm nv173-kernel/precompiled;
	xmv nv173-kernel/nv-kernel.o "nv173-kernel/nv-kernel_$arch.bin";
}

if [[ -x "$nv173_x64.run" ]] && [[ -x "$nv173_x86.run" ]]; then
	"./$nv173_x64.run" --extract-only;
	"./$nv173_x86.run" --extract-only;

	nv173_list "$nv173_x86" x86;
	nv173_list "$nv173_x64" x64;

	xrmdir "$nv173_x64" "$nv173_x86";
	parts="$parts nv173";
fi;

function nv96_list
{
	local dir="$1";
	local arch="$2";
	local lib="$(libdir $arch)";

	xrm "$dir"/{.manifest,nvidia-installer,pkg-history.txt};
	xrm "$dir/usr/X11R6/lib/libXvMCNVIDIA.a";
	xmv "$dir"/usr/X11R6/lib/libXvMCNVIDIA.so.* "nv96-$arch/usr/X11R6/$lib/";
	xmv "$dir/usr/X11R6/lib/modules/drivers/" "nv96-$arch/usr/$lib/xorg/modules/drivers/";
	xmv "$dir/usr/X11R6/lib/modules/extensions/" "nv96-$arch/usr/$lib/xorg/modules/updates/extensions/";
	xrm "$dir"/usr/bin/{makeself.sh,mkprecompiled};
	xmv "$dir"/usr/bin/nvidia-bug-report.sh nv96-noarch/usr/bin/;
	xmv "$dir"/usr/bin/nvidia-{settings,xconfig} "nv96-$arch"/usr/bin/;
	xrm "$dir"/usr/bin/tls_test*;
	xmv "$dir"/usr/include/* nv96-noarch/usr/include/nvidia/;
	xrm "$dir"/usr/lib/libGL.la;
	xmv "$dir"/usr/lib/libGL*.so.* "nv96-$arch/usr/X11R6/$lib/";
	xmv "$dir"/usr/lib/lib*.so.* "nv96-$arch/usr/$lib/";
	xmv "$dir"/usr/lib/tls/ "nv96-$arch/usr/$lib/tls/";
	xrm "$dir/usr/lib32";
	xmv "$dir"/usr/share/applications/ nv96-noarch/usr/share/applications/;
	xmv "$dir"/usr/share/doc/ nv96-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/LICENSE nv96-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/usr/share/man/ nv96-noarch/usr/share/man/;
	xmv "$dir"/usr/share/pixmaps/ nv96-noarch/usr/share/pixmaps/;
	xmv "$dir"/usr/src/nv/ nv96-kernel/;
	xrm nv96-kernel/precompiled;
	xmv nv96-kernel/nv-kernel.o "nv96-kernel/nv-kernel_$arch.bin";
}

if [[ -x "$nv96_x64.run" ]] && [[ -x "$nv96_x86.run" ]]; then
	"./$nv96_x64.run" --extract-only;
	"./$nv96_x86.run" --extract-only;

	nv96_list "$nv96_x86" x86;
	nv96_list "$nv96_x64" x64;

 	xrmdir "$nv96_x64" "$nv96_x86";
	parts="$parts nv96";
fi;

function nv71_list
{
	local dir="$1";
	local arch="$2";
	local lib="$(libdir $arch)";

	xrm "$dir"/{.manifest,nvidia-installer,pkg-history.txt};
	xrm "$dir/usr/X11R6/lib/libXvMCNVIDIA.a";
	xmv "$dir"/usr/X11R6/lib/libXvMCNVIDIA.so.* "nv71-$arch/usr/X11R6/$lib/";
	xmv "$dir/usr/X11R6/lib/modules/drivers/" "nv71-$arch/usr/$lib/xorg/modules/drivers/";
	xmv "$dir/usr/X11R6/lib/modules/extensions/" "nv71-$arch/usr/$lib/xorg/modules/updates/extensions/";
	xrm "$dir"/usr/bin/{makeself.sh,mkprecompiled};
	xmv "$dir"/usr/bin/nvidia-bug-report.sh nv71-noarch/usr/bin/;
	xmv "$dir"/usr/bin/nvidia-settings "nv71-$arch"/usr/bin/;
	xrm "$dir"/usr/bin/tls_test*;
	xmv "$dir"/usr/include/* nv71-noarch/usr/include/nvidia/;
	xrm "$dir"/usr/lib/libGL.la;
	xmv "$dir"/usr/lib/libGL*.so.* "nv71-$arch/usr/X11R6/$lib/";
	xmv "$dir"/usr/lib/lib*.so.* "nv71-$arch/usr/$lib/";
	xmv "$dir"/usr/lib/tls/ "nv71-$arch/usr/$lib/tls/";
	xrm "$dir/usr/lib32";
	xmv "$dir"/usr/share/applications/ nv71-noarch/usr/share/applications/;
	xmv "$dir"/usr/share/doc/ nv71-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/LICENSE nv71-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/usr/share/man/ nv71-noarch/usr/share/man/;
	xmv "$dir"/usr/share/pixmaps/ nv71-noarch/usr/share/pixmaps/;
	xmv "$dir"/usr/src/nv/ nv71-kernel/;
	xrm nv71-kernel/precompiled;
	xmv nv71-kernel/nv-kernel.o "nv71-kernel/nv-kernel_$arch.bin";
}

if [[ -x "$nv71_x64.run" ]] && [[ -x "$nv71_x86.run" ]]; then
	"./$nv71_x64.run" --extract-only;
	"./$nv71_x86.run" --extract-only;

	nv71_list "$nv71_x86" x86;
	nv71_list "$nv71_x64" x64;

	xrmdir "$nv71_x64" "$nv71_x86";
	parts="$parts nv71";
fi;	

lines=$(find "$nv270_x64" "$nv270_x86" \
	"$nv173_x64" "$nv173_x86" "$nv96_x64" "$nv96_x86" \
	"$nv71_x64" "$nv71_x86" | wc -l);
if [[ "$lines" -ne 0 ]]; then
	echo File list does not match.
	exit 1;
fi;

for i in $parts; do
	for j in noarch x64 x86; do
		# Needless to mention their SONAMEs are also fucked up
		find "$i-$j" -type d -print0 | sort -z | xargs -0 ldconfig -N;
		pushd "$i-$j/";
		qtar "../$i-$j.tar.xz" *;
		popd;
	done;
	qtar "$i-kernel.tar.xz" "$i-kernel";
done;

xcleanup;
