#!/usr/bin/perl

# ADDXCOM - PROGRAM FOR ADDING XCOM AND TST MODIFICATIONS TO WEBSITES
# ------------------------------------------------------------------------------

# use warnings ;
use strict ;
use Cwd ;

use File::Copy ;
use File::Spec ;

print "\n" ;
print "******************************************************\n" ;
print "*                                                    *\n" ;
print "*  ADDXCOM - Quickly XComponent-enable your website  *\n" ;
print "*                                                    *\n" ;
print "******************************************************\n" ;

unless ( defined @ARGV ) {
	print "Usage perl addxcom.pl [/path/to/directory]\nPlease specify the directory containing your website.\n\n" ;
	exit ;
}
my $workingdir = pop @ARGV ;
chomp $workingdir ;
$workingdir = File::Spec->canonpath($workingdir) ;

print "This program will batch processes the files in $workingdir/\n" ;
print "creating a copy of your website in $workingdir"  . "_XCOM/\n" ;
print "and adding the XComponent/TST modifications to .php files,\n" ;
print "and the TST modifications to .htm and .html files.\n" ;
print "All other files will be copied verbatim.\n" ;
print "\n" ;

my $outputdir = File::Spec->rel2abs($workingdir . '_XCOM') ;
mkdir ($outputdir, 0777) || die "ERROR: System is unable to create output directory $outputdir/\n" ;
opendir (OUTPUTDIR, $outputdir) || die "ERROR: System cannot open directory $outputdir/" ;
closedir(OUTPUTDIR) ;
print "Program will output files to directory:\n" ;
print "$outputdir/\n" ;
print "\n" ;

# DEFINE <head> MODIFICACATIONS (in variables for legibility)
# ------------------------------------------------------------------------------

my $mod_head_xcom = '
<?php
// Start XComponents: Initialise XComponents session in page, and add TST libraries
dmx_initialise_trolley();
dmx_include_tst();
?>';

my $mod_head_tst = '
<!-- TST JS -->
<script language="javascript" src="/dmx/core/tst/js/include_tst.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">tst_manage_session();</script>
<!-- END TST JS -->';

# BATCH PROCESS THE SITE
# ------------------------------------------------------------------------------

print "HERE WE GO: STARTING BATCH PROCESS\n" ;
print "----------------------------------\n" ;

my $indent     = '';
my $indent_add = '    ';
my $current_outputdir = $outputdir ;
chdir $workingdir or die "ERROR: Cannot change working directory to $workingdir: $!" ;
recursive_batch($_) ;

print "\n" ;
print "FINISHED PROCESSING WEBSITE.\n" ;
print "\n" ;

# THIS IS THE END OF THE MAIN FLOW
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------

# SUBROUTINES...
# ------------------------------------------------------------------------------

sub recursive_batch {
	foreach (glob "*") {
		if ( -d $_ ) {
			my $old_sourcedir = getcwd ;
			my $old_outputdir = $current_outputdir ;
			$current_outputdir = File::Spec->catfile($current_outputdir, $_) ;
			mkdir ($current_outputdir, 0777) or die "ERROR: Cannot create sub-directory $_ in output directory: $!" ;
			chdir $_ or die "ERROR: Cannot change to sub-directory $old_sourcedir/$_: $!" ;
			
			if ($_ ne 'dmx') {
				print $indent . ">>> CHANGING TO SUB-DIRECTORY: $_\n" ;
				$indent .= $indent_add;
				recursive_batch() ;
			} else {
				print $indent . ">>> COPYING dmx SUB-DIRECTORY\n" ;
				$indent .= $indent_add;
				copy_directory() ;
			}
			$indent = substr($indent, 0, length($indent)-4);
			
			chdir $old_sourcedir ;
			$current_outputdir = $old_outputdir ;
		}
		elsif ( -f $_ ) {
			if (/.*.php/) {
				print $indent . "Adding XCom modifications to $_\n" ;
				run_regex_xcom() ;
			} elsif (/.*.html?/) {
				print $indent . "Adding TST modifications to $_\n" ;
				run_regex_tst() ;
			} else {
				print $indent . "Copying $_\n" ;
				copy($_, File::Spec->catfile($current_outputdir, $_)) ;
			}
		}
	}
}

# ------------------------------------------------------------------------------

sub copy_directory {
	foreach (glob "*") {
		if ( -d $_ ) {
			my $old_sourcedir = getcwd ;
			my $old_outputdir = $current_outputdir ;
			$current_outputdir = File::Spec->catfile($current_outputdir, $_) ;
			mkdir ($current_outputdir, 0777) or die "ERROR: Cannot create sub-directory $_ in output directory: $!" ;
			chdir $_ or die "ERROR: Cannot change to sub-directory $old_sourcedir/$_: $!" ;
			
			print $indent . ">>> COPYING $_ SUB-DIRECTORY\n" ;
			$indent .= $indent_add;
			copy_directory() ;
			$indent = substr($indent, 0, length($indent_add));
		
			chdir $old_sourcedir ;
			$current_outputdir = $old_outputdir ;
		}
		elsif ( -f $_ ) {
			print $indent . "Copying $_\n" ;
			copy($_, File::Spec->catfile($current_outputdir, $_)) ;
		}
	}
}

# ------------------------------------------------------------------------------

sub run_regex_xcom {
	open INFILE, "<$_" or die "ERROR: Cannot open file $_: $!" ;
	open OUTFILE, ">" . File::Spec->catfile($current_outputdir, $_) or die "ERROR: Cannot create file $_: $!" ;
	select OUTFILE ;
	
	# Check first line of file for dircetive to exclude some or all xcom modifications
	my $ex_directive = 0 ;
	my $ex_eng ; my $ex_head ; my $ex_tst ; my $ex_all ;
	my $flags = <INFILE> ;
	if ($flags =~ /^\s*<\?php\s+\/\/\s*DMXCLUDE/i) {
		$ex_directive = 1;
		$ex_eng  = $flags =~ /ENG/i ;
		$ex_head = $flags =~ /HEAD/i ;
		$ex_tst  = $flags =~ /TST/i ;
		$ex_all  = $flags =~ /ALL/i ;
		<INFILE> ;
	}
	
	if (<INFILE> !~ /^\/\/ Call in the XComponents/ && !$ex_eng && !$ex_all) {
		# Add the XCom libraries on the first line, keeping the DMXCLUDE directive if there was one
		print $ex_directive ? $flags : '' ;
		print "<?php\n" ;
		print "// Call in the XComponents engine and options file\n" ;
		print "include(\DOCROOT . '/dmx/dmx_options.php');\n" ;
		print "include(\DOCROOT . '/dmx/dmx_shop_handler.php');\n" ;
		print "include(\DOCROOT . '/dmx/dmx_shop_components.php');\n" ;
		print "?>\n" ;
	}
	
	seek(INFILE, 0, 0) ;
	$ex_directive ? <INFILE> : '';
	while (<INFILE>) {
		# Parse every line with these regex...
		!$ex_head && !$ex_all ? s/<\/head>(?! <!-- XCom & TST modifications added -->)/$mod_head_xcom\n<\/head> <!-- XCom & TST modifications added -->/i : '' ;
		!$ex_tst && !$ex_all ? tst_links_forms() : '' ;
		print "$_" ;
	}
	
	close INFILE ;
	close OUTFILE ;
	select STDOUT ;
}

# ------------------------------------------------------------------------------

sub run_regex_tst {
	open INFILE, "<$_" or die "ERROR: Cannot open file $_: $!" ;
	open OUTFILE, ">" . File::Spec->catfile($current_outputdir, $_) or die "ERROR: Cannot create file $_: $!" ;
	select OUTFILE ;
	
	while (<INFILE>) {
		# Parse every line with these regex...
		s/<\/head>(?! <!-- TST modifications added -->)/$mod_head_tst\n<\/head> <!-- TST modifications added -->\n/i ;
		tst_links_forms() ;
		print "$_" ;
	}
	
	close INFILE ;
	close OUTFILE ;
	select STDOUT ;
}

# ------------------------------------------------------------------------------

sub tst_links_forms {
	s/<a\s+(?!href=['|"]?#)(?!name=)(?!.*onclick="return tst_follow_link\(this\);")(.*?)>/<a \1 onclick="return tst_follow_link(this);">/i ;
	s/<form\s+(?!.*onsubmit="tst_submit_form\(this\);")(.*?)>/<form \1 onsubmit="tst_submit_form(this);">/i ;
}

# ------------------------------------------------------------------------------
