#!/usr/bin/perl
use Switch;
use File::Copy;
use Getopt::Std;

	# ******************************
	# CMDline args
	# ******************************

	getopts('hv');

$usage = qq{
$0 downloads the contents of the GridSite Wiki and uses that to produce EMI-style PDF documentation.

usage: $0 [-h] [-v]
	
-h  Print this help and exit
-v  Verbose output

};
	if (defined $opt_h) {die $usage};

	if (defined $opt_v) {
		$qopt_devnull="";
		$qopt_q="";
	}
	else {
		$qopt_devnull=" > /dev/null 2> /dev/null";
		$qopt_q="-q";
	}


	# ******************************
	# Init All
	# ******************************

	printf("Checking for required binaries...");
	check_req("rm", "mv", "mkdir", "grep", "egrep", "wget", "cat", "awk", "sed", "gnuhtml2latex", "pdflatex", "base64", "convert");

	printf("\nSetting up...");
	$TMPDIR=$ENV{'TMPDIR'};
	if ($TMPDIR eq "") {$TMPDIR="/tmp";}

#	$WRKDIR="/tmp/gsdoc_2989"; # XXX: back to autodetect
	$WRKDIR="$TMPDIR/gsdoc_$$";
	system("mkdir -p $WRKDIR");
	chdir($WRKDIR);

#	system("rm -f striphead_* striptail_* *.html *.tex *.cls *.pdf GridSite_all.* GridSite_UG.* GridSite_AG.* GridSite_DESC.* .* *.gif *.png");

	# ******************************
	# Hard-code contents
	# ******************************

	# This is a set of arrays that define contents of various documents.
	# Give names of individual wiki pages to include them into the doc
	# 'all' will first include all the listed pages and then all unlisted
	# ones

	%docs = (
		UG => [ qw/User_Guide/ ],
		AG => [ qw/Build_and_Install_Guide Config_Guide Administration_Guide/ ],
		DESC => [ qw/Module_Architecture Delegation_protocol/ ],
		all => [ qw/ GridSite Module_Architecture / ]
	);

	%titles = (
		UG => 'GridSite -- User Guide', 
		AG => 'GridSite -- Administrator Guide', 
		DESC => 'GridSite -- Functional Description', 
		all => 'GridSite' 
	);

	# ******************************
	# Get Content
	# ******************************

	printf("\nDownloading content...");
	system("wget --no-check-certificate $qopt_q -r -l 1 -nd -k -p -I wiki --no-parent https://www.gridsite.org/wiki/Special:Allpages");
	system("rm -f $WRKDIR/*:*");
	

	opendir(WRKD, $WRKDIR) || die("Cannot open directory $WRKDIR");
	@allfiles = readdir(WRKD);
	closedir(WRKD);

	# ******************************
	# Prepare LaTeX structures
	# ******************************

	gen_emi_cls();
	gen_emi_logo();
	gen_wget();

	# ******************************
	# Produce LaTeX chapters
	# ******************************

	printf("\nProcessing files...");

	foreach $f (@allfiles) {
		unless ( ($f eq ".") || ($f eq "..") ) {
			#Get and prepend Title
			$title=`egrep -a "class=.firstHeading.>" $f `;
			$title=~s/<\/{0,1}h1.*?>//g;
			chomp($title);
			system("echo '<HTML><BODY><H1>$title</H1>' > $f.html");
			
			# Strip front and tail matter
			system("awk '!p;/-- end content --/{p=1}' $f | awk '/-- start content --/{p=1}p' >> $f.html");

			# Remove Table of Contents, if present
			$toc_present=`grep -E 'table.*toctitle' $f.html`;
			unless ($toc_present eq "") {
				system("awk '!p;/<table.*toctitle/{p=1}' $f.html | egrep -v '<table.*toctitle' > $f.front.html");
				system("awk '/<.table>/{p=1}p' $f.html | tail -n +2 > $f.rear.html");

				system("cat $f.front.html > $f.html");
				system("cat $f.rear.html >> $f.html");

				system("rm $f.front.html $f.rear.html");
			}

			# Add false beginings and ends
			system("echo '</BODY>' >> $f.html");
			system("echo '</HTML>' >> $f.html");

			# Convert format, making sure that fake wget gets called first :-/
			# This is a workaround for an apparent bug in gnuhtml2latex v 0.4-1,
			# which sticks option -nc between -O and the actual file name.
			system("PATH=.:\$PATH gnuhtml2latex -a EMI -n -g $f.html $qopt_devnull");

			# Strip LaTeX matter
			system("mv $f.tex $f.latex");
			system("awk '!p;/end{document}/{p=1}' $f.latex | awk '/begin{document}/{p=1}p' | egrep -v 'end{document}' | egrep -v 'begin{document}' >> $f.tex");
			system("rm $f.latex");

			# Custom fixes
			system("sed -i 's/^\\\\par \\\\\\\\//' $f.tex"); #Remove empty paragraphs
			system("sed -i 's/^\\[edit\\]//' $f.tex"); #Remove remaining [edit] clauses
			system("sed -i 's/^Retrieved from.*//' $f.tex"); #Remove "retrieved from" remarks
			system("sed -i 's/^Categories:.*//' $f.tex"); #Remove wiki categories
			system("sed -i 's/\\\\par Categories:.*//' $f.tex"); #Remove wiki categories, take 2

#			printf("\n$f ready");

		}
	}
	
	# *************************************
	# Convert unsupported graphics formats
	# *************************************

	printf("\nConverting unsupported graphic formats...");

	@presentfiles = <*>;

	@extensions = ( "gif", "jpg", "jpeg", "tif", "tiff" );

	$i = 0;

	foreach $img (@presentfiles) {
		foreach $ext (@extensions) {
			if ($img=~m/\.$ext$/i) {
				move($img,"inclfile$i.$ext");
				system("convert inclfile$i.$ext inclfile$i.png");
				system("sed -i 's/$img/inclfile$i.png/' *.tex");
				$i++;
			}
		}
	}

	# ******************************
	# Generate overall LaTeX files
	# ******************************

	printf ("\nGenerating LaTeX doc files...");

	for $doc ( keys %docs ) {

		$texfilename = sprintf "GridSite_$doc.tex";

		if (defined $opt_v) { printf "\n* $doc ($titles{$doc}): $texfilename"; }

		gen_LaTeX_files($texfilename);

		system("sed -i 's/XXTITLEXX/$titles{$doc}/' $texfilename");
		system("sed -i 's/XXAUTHORXX/CESNET/' $texfilename");
		system("sed -i 's/XXVERSIONXX/1.0.0-1/' $texfilename");
		system("sed -i 's/XXEMIVERSIONXX/1.x/' $texfilename");

		foreach $chapter (@{ $docs{$doc} }) {
			if (defined $opt_v) { printf "\n - $chapter"; }
			# Add to final document
			system("echo \"\\input{$chapter.tex}\" >> $texfilename");
		}
	}


	# Special treatment of 'all'
	printf("\nAdding all unlisted to 'GridSite_all'...");
	foreach $f (@allfiles) {
		unless ( ($f eq ".") || ($f eq "..") ) {
			unless(grep $_ eq $f, @{ $docs{all} }) {
				system("echo \"\\input{$f.tex}\" >> GridSite_all.tex");
				if (defined $opt_v) { printf("\n  - $f"); }
			}
		}
	}

	for $doc ( keys %docs ) {

		$texfilename = sprintf "GridSite_$doc.tex";
		system("echo '\\end{document}' >> $texfilename");
	}

	# ******************************
	# Build
	# ******************************

	printf("\nBuilding PDFs...");
	for $doc ( keys %docs ) {
		$texfilename = sprintf "GridSite_$doc.tex";
		system("pdflatex $texfilename $qopt_devnull");
		system("pdflatex $texfilename $qopt_devnull"); #Twice for TOC, page and ref. numbers to regenerate correctly.
	}

	# ******************************
	# Final Bows
	# ******************************


	printf("\n\nOutput is in $WRKDIR\n");
	for $doc ( keys %docs ) {
		$pdffilename = sprintf "GridSite_$doc.pdf";
		printf("$WRKDIR/$pdffilename\n");
	}
	printf ("\n");

	# ******************************
	# Subroutines
	# ******************************


sub check_req {

	my $fail=0;

	for($i=0;$i<=$#_;$i++){
		system("which $_[$i] > /dev/null");
		if ($? >> 8) { printf "\n$_[$i]... Not found"; $fail = 1; }
		else {
			if (defined $opt_v) { printf "\n$_[$i]... OK"; }
		}
	}

	if ($fail) {printf "\n\nSome required binaries were not found!\n"; die; }
}


sub gen_wget {

	open T,">wget.b64" or die "wget.b64: $!\n";

	print T q{IyEvdXNyL2Jpbi9wZXJsCgokYXJncyA9IGpvaW4gIiAiLCBAQVJHVjsKCiRhcmdzPX5zLy1uYyAv
LzsKc3lzdGVtKCJYWFdHRVRYWCAtLW5vLWNoZWNrLWNlcnRpZmljYXRlICRhcmdzIik7Cg==};

	close T;
	system("base64 -d -i wget.b64 > wget");
	system("rm wget.b64");

	$wgetpath=`which wget`;
	chomp($wgetpath);
	system("sed -i 's!XXWGETXX!$wgetpath!' ./wget");
	system ("chmod +x ./wget");

}

sub gen_LaTeX_files {

#	printf "gen_LaTeX_files: $_[0]";

	open T,">$_[0].b64" or die "$_[0].b64: $!\n";

	print T q{XGRvY3VtZW50Y2xhc3NbXXtlbWl9Clx1c2VwYWNrYWdlW3V0Zjhde2lucHV0ZW5jfQpcdXNlcGFj
a2FnZVtwZGZ0ZXhde2dyYXBoaWN4fQpcdXNlcGFja2FnZVtde2NvbW1lbnR9CgpcdGl0bGV7WFhU
SVRMRVhYfQpcYXV0aG9ye1hYQVVUSE9SWFh9ClxEYXRle1x0b2RheX0KXERvY1ZlcnNpb257WFhW
RVJTSU9OWFh9ClxFTUlDb21wVmVyc2lvbntYWEVNSVZFUlNJT05YWH0KClxiZWdpbntkb2N1bWVu
dH0KClx0YWJsZW9mY29udGVudHMKClxuZXdwYWdlCgo=};

	close T;
	system("base64 -d -i $_[0].b64 > $_[0]");
	system("rm $_[0].b64");

}

sub gen_emi_cls {
	open T,">emi.cls.b64" or die "emi.cls.b64: $!\n";

	print T q{CgpcTmVlZHNUZVhGb3JtYXR7TGFUZVgyZX0KXFByb3ZpZGVzQ2xhc3N7ZW1pfVsyMDExLzAzLzI0
[encoded data, 10472 characters]
ZXs1fXsxMGVtfXs1ZW19fQoK};

	close T;

	system("base64 -d -i emi.cls.b64 > emi.cls");
	system("rm emi.cls.b64");

}

sub gen_emi_logo {
	open T,">EMI_Logo_std.pdf.b64" or die "EMI_Logo_std.pdf.b64: $!\n";

	print T q{JVBERi0xLjQKJcfsj6IKNiAwIG9iago8PC9MZW5ndGggNyAwIFIvRmlsdGVyIC9GbGF0ZURlY29k
[encoded data, 46816 characters]
Q0YyOTJBMDM2REIzQUMxRkExNzdERjE+XQo+PgpzdGFydHhyZWYKMzI5MzAKJSVFT0YK};

	system("base64 -d -i EMI_Logo_std.pdf.b64 > EMI_Logo_std.pdf");
	system("rm EMI_Logo_std.pdf.b64");

}

