#!/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 {nv260,nv195,nv173,nv96,nv71}-{noarch,kernel,x64,x86};
	xrm "$nv260_x64" "$nv260_x86";
	xrm "$nv195_x64" "$nv195_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_nv260="260.19.36";
ver_nv256="256.53";
ver_nv195="195.36.31";
ver_nv173="173.14.28";
ver_nv96="96.43.19";
ver_nv71="71.86.14";
nv260_x64="NVIDIA-Linux-x86_64-$ver_nv260";
nv260_x86="NVIDIA-Linux-x86-$ver_nv260";
nv256_x64="NVIDIA-Linux-x86_64-$ver_nv256";
nv256_x86="NVIDIA-Linux-x86-$ver_nv256";
nv195_x64="NVIDIA-Linux-x86_64-$ver_nv195-pkg2";
nv195_x86="NVIDIA-Linux-x86-$ver_nv195-pkg1";
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 nv260_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/ nv260-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/LICENSE nv260-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/kernel/ nv260-kernel/;
	xmv "nv260-kernel/nv-kernel.o" "nv260-kernel/nv-kernel_$arch.bin";
	xmv "$dir"/gl*.h nv260-noarch/usr/include/nvidia/GL/;
	xmv "$dir"/libglx.so* "nv260-$arch/usr/$lib/xorg/modules/updates/extensions/";
	xmv "$dir"/*_drv.so "nv260-$arch/usr/$lib/xorg/modules/drivers/";
	xmv "$dir"/libGL.so* "nv260-$arch/usr/X11R6/$lib/";
	xmv "$dir"/lib*.so* "nv260-$arch/usr/$lib/";
	ln -s libcuda.so.1 "nv260-$arch/usr/$lib/libcuda.so"; # libcudart.so wants this
	xmv "$dir"/*.1.gz nv260-noarch/usr/share/man/man1/;
	xmv "$dir"/nvidia-{settings,smi,xconfig} "nv260-$arch/usr/bin/";
	xmv "$dir/nvidia-bug-report.sh" nv260-noarch/usr/bin/;
	xmv "$dir"/*.desktop nv260-noarch/usr/share/applications/;
	xmv "$dir"/nvidia-settings.png nv260-noarch/usr/share/pixmaps/;
	xmv "$dir"/nvidia.icd nv260-noarch/etc/OpenCL/vendors/;
	xmv "$dir"/tls/ "nv260-$arch/usr/$lib/tls/";
}

if [[ -x "$nv260_x64.run" ]] && [[ -x "$nv260_x86.run" ]]; then
	"./$nv260_x64.run" --extract-only;
	"./$nv260_x86.run" --extract-only;

	nv260_list "$nv260_x86" x86;
	nv260_list "$nv260_x64" x64;

	xrmdir "$nv260_x64" "$nv260_x86";
	parts="$parts nv260";
fi;

function nv256_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/ nv256-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/LICENSE nv256-noarch/usr/share/doc/packages/nvidiagfx/;
	xmv "$dir"/kernel/ nv256-kernel/;
	xmv "nv256-kernel/nv-kernel.o" "nv256-kernel/nv-kernel_$arch.bin";
	xmv "$dir"/cl*.h nv256-noarch/usr/include/nvidia/CL/;
	xmv "$dir"/cuda*.h nv256-noarch/usr/include/nvidia/cuda/;
	xmv "$dir"/gl*.h nv256-noarch/usr/include/nvidia/GL/;
	xmv "$dir"/vdpau*.h nv256-noarch/usr/include/nvidia/vdpau/;
	xmv "$dir"/libglx.so* "nv256-$arch/usr/$lib/xorg/modules/updates/extensions/";
	xmv "$dir"/*_drv.so "nv256-$arch/usr/$lib/xorg/modules/drivers/";
	xmv "$dir"/libGL.so* "nv256-$arch/usr/X11R6/$lib/";
	xmv "$dir"/lib*.so* "nv256-$arch/usr/$lib/";
	xmv "$dir"/*.1.gz nv256-noarch/usr/share/man/man1/;
	xmv "$dir"/nvidia-{settings,smi,xconfig} "nv256-$arch/usr/bin/";
	xmv "$dir/nvidia-bug-report.sh" nv256-noarch/usr/bin/;
	xmv "$dir"/*.desktop nv256-noarch/usr/share/applications/;
	xmv "$dir"/nvidia-settings.png nv256-noarch/usr/share/pixmaps/;
	xmv "$dir"/nvidia.icd nv256-noarch/etc/OpenCL/vendors/;
	xmv "$dir"/tls/ "nv256-$arch/usr/$lib/tls/";
}

if [[ -x "$nv256_x64.run" ]] && [[ -x "$nv256_x86.run" ]]; then
	"./$nv256_x64.run" --extract-only;
	"./$nv256_x86.run" --extract-only;

	nv256_list "$nv256_x86" x86;
	nv256_list "$nv256_x64" x64;

	xrmdir "$nv256_x64" "$nv256_x86";
	parts="$parts nv256";
fi;

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

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

if [[ -x "$nv195_x64.run" ]] && [[ -x "$nv195_x86.run" ]]; then
	"./$nv195_x64.run" --extract-only;
	"./$nv195_x86.run" --extract-only;

	nv195_list "$nv195_x86" x86;
	nv195_list "$nv195_x64" x64;

	xrmdir "$nv195_x64" "$nv195_x86";
	parts="$parts nv195";
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 "$nv260_x64" "$nv260_x86" "$nv256_x64" "$nv256_x86" "$nv195_x64" \
	"$nv195_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;
