#!/usr/bin/perl -w
#
# Makedistrib.pl: create package to be distributed. In the
# Windows environment expect to find the dmake command.
#
# Laurent.Gougeon@ecmwf.int - 2011-09-21
#
# Required libraries to run this script:
#
#  perl -MCPAN -e "install PAR"
#  perl -MCPAN -e "install PAR::Packer"
#  perl -MCPAN -e "install Archive::Tar"
#
# This script must be started from the source
# directory.

use Cwd;
use File::Path;
use File::Copy;
use Archive::Tar;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );

#
# Function to start an external command
#
sub execCmd($$) {
	my $command      = $_[0];
	my $expectedCode = $_[1];
	print "# " . $command . "\n";
	my $result = `$command 2>&1`;
	die "Error: $! (exit-code = $?)\n" if $expectedCode != -1 && not( $? >> 8 == $expectedCode );
	print $result;
	return $result;
}

#
# Where to install the ECMWF module?
#
my $installBase = "";

#
# Set the PERL5LIB environment parameter to install the ECMWF module
# in the source directory if "ecaccess-perl5" is defined. Otherwise
# the module is installed in the standard directories.
#
if ( $ENV{'PERL5LIB'} ) {
	my $perl5lib = $ENV{'PERL5LIB'};
	my $index = index( $perl5lib, 'ecaccess-perl5' );
	if ( $index != -1 ) {
		my $find = quotemeta substr( $perl5lib, 0, $index );
		$perl5lib =~ s/$find//g;
		$ENV{'PERL5LIB'} = $perl5lib . ":" . $ENV{'PERL5LIB'};
		$installBase = " INSTALL_BASE=ecaccess-perl5";
	}
}

#
# Get the ECaccess version number from the current directory
# name
#
my $cwd     = getcwd();
my $version = substr $cwd, -5, length($cwd);
my $make    = "make";

#
# Get the target system name (OS)
#
my $system;
if ( $^O =~ /^MSWin/ ) {
	$system = "windows";
	$make   = "dmake";
}
else {
	my $unameS = execCmd "uname -s", 0;
	my $unameM = execCmd "uname -m", 0;
	chomp($unameS);
	chomp($unameM);

	if ( $ENV{'ECACCESS_WEBTOOLKIT_PERL_TARGET_OS'} ) {
		$unameS = $ENV{'ECACCESS_WEBTOOLKIT_PERL_TARGET_OS'};
	}

	$system = $unameS . "-" . $unameM;
}

#
# Make, test and install the ECMWF module.
#
execCmd "perl Makefile.PL" . $installBase, 0;
execCmd $make, 0;
execCmd $make . " test",    0;
execCmd $make . " install", 0;

#
# Build the package name
#
my $packageName = "ecaccess-webtoolkit-" . $version . "-" . $system;
print "Creating package " . $packageName . "\n";

#
# Clean/create the target directory
#
rmtree "$packageName";
mkdir "$packageName";

#
# Get the list of scripts from the MANIFEST
#
my $scriptsList = "";
open( MANIFEST, "MANIFEST" );
while ( $record = <MANIFEST> ) {
	chomp($record);
	$scriptsList = "$scriptsList $record" if ( $record =~ m/^script/ );
}
close(MANIFEST);

# Runtime dependencies and options
my $dependencies = "--compress=9";

#
# Create the distribution
#
if ( $^O =~ /^MSWin/ ) {

	#
	# Process the Windows package
	#
	execCmd "pp " . $dependencies . " -M IO::Socket::SSL --output=$packageName/ecaccess-command.exe script/ecaccess-command $scriptsList", 0;

	# Goto the distrib directory
	chdir $packageName or die "Chdir failed ($packageName):  $!\n";

	# Create the bat files
	foreach ( split( / /, $scriptsList ) ) {
		$name = $_;
		if ( length($name) > 7 ) {
			my $scriptName = ( substr $name, 7 );
			print "Create ", $scriptName, ".bat file\n";
			open FILE, ">$scriptName" . ".bat" or die $!;
			print FILE "\@rem -------------------------------------------------------------\n";
			print FILE "\@rem Helper to start the $scriptName command from the\n";
			print FILE "\@rem ecaccess-command.exe file.\n";
			print FILE "\@rem \n";
			print FILE "\@rem Laurent.Gougeon\@ecmwf.int - 2012-02-09\n";
			print FILE "\@rem -------------------------------------------------------------\n";
			print FILE "\@%~dp0\\ecaccess-command.exe $scriptName %*\n";
			close FILE;
		}
	}

	# Go back to the main directory
	chdir "..";
}
else {

	#
	# Process the Unix packages
	#
	execCmd "pp " . $dependencies . " -M arybase -M IO::Socket::INET6 -M IO::Socket::SSL -M Pod::Text --output=$packageName/.ecaccess-command script/ecaccess-command $scriptsList", 0;

	# Goto the distrib directory
	chdir $packageName or die "Chdir failed ($packageName):  $!\n";

	# Create the links/copies
	$source = ".ecaccess-command";
	foreach ( split( / /, $scriptsList ) ) {
		$name = $_;
		if ( length($name) > 7 ) {
			my $scriptName = substr $name, 7;
			print "ln ", $source, "->", $scriptName, "\n";
			symlink $source, $scriptName;
			execCmd "./$scriptName -v", -1;
		}
	}

	# Go back to the main directory
	chdir "..";
}

#
# Build the list of files to distribute
#
@archivefiles = <$packageName/*>;

#
# Push the ecaccess helper
#
push( @archivefiles, "$packageName/.ecaccess-command" )    if ( not $^O =~ /^MSWin/ );
push( @archivefiles, "$packageName/ecaccess-command.exe" ) if ( $^O     =~ /^MSWin/ );

#
# Compress the distribution files
#
print "Packing distribution\n";

if ( not $^O =~ /^MSWin/ ) {
	Archive::Tar->create_archive( "$packageName" . ".tar.gz", 9, @archivefiles ) or die "Create tar.gz failed ($packageName):  $!\n";
}
else {

	# Create a Zip file
	my $zip = Archive::Zip->new();

	# Add a directory
	$zip->addTree( $packageName . "/" );

	# Save the Zip file
	unless ( $zip->writeToFileNamed( "$packageName" . ".zip" ) == AZ_OK ) {
		die "Create zip failed ($packageName):  $!\n";
	}
}
