#!/usr/bin/env perl

##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
## 
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
## 
##    http://www.apache.org/licenses/LICENSE-2.0
## 
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************



# tab stops are 4
# ===========================================================================
# make-nmi-gpt-dist - a script to build a Condor-G GPT package from a static or
# stripped release dir
# This script started out as gbuild, from Globus. 
# ===========================================================================

#use strict;

use Getopt::Long;
use Cwd;
use Config;

my $Compiler = "gcc32";  #only used for ia64

if ($Config{'archname'} =~ m!i386-linux!)
{
	$ENV{'PATH'} = ".:/usr/local/sbin:/usr/local/bin:" . $ENV{'PATH'};
	#$ENV{PATH} = '.:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/ucb:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/ucb';
	print "Adjusting component build for Linux x86\n";
	$TargetDir = i386_rh72;

	open(PULL, "gcc -v 2>&1 |") || die "gcc version info: $!\n";
	while (<PULL>)
	{
		print "Compiler info....: ";
		print $_;
		if( $_ =~ m/2.95.2/ )
		{
			print "Running edg requested compiler, must be i386rh72gcc2952\n";
			$TargetDir = i386rh72gcc2952;
		}
	}
	close(PULL);

	if( -e "REDHAT80" )
	{
		$ENV{'PATH'} = ".:/opt/gcc3/bin:/usr/local/sbin:/usr/local/bin:" . $ENV{'PATH'};
		#$ENV{PATH} = '.:/opt/gcc3/bin:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/ucb:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/ucb';
		print "We are told it is Redhat 80, so i386_rh80\n";
		$TargetDir = i386_rh80;
		$IsIa32Rh80 = "yes";
	}

}



if ($Config{'archname'} =~ m!ia64-linux!)
{
	$ENV{'PATH'} = ".:/usr/local/sbin:/usr/local/bin:" . $ENV{'PATH'};
	#$ENV{PATH} = '.:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/ucb:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/ucb';
	print "Adjusting component build for Linux ia64\n";
	$Compiler = "gcc64";
	if( -e "SLES8" )
	{
		print "We are told it is SLES 8, so ia64_sles8\n";
		$TargetDir = ia64_sles8;
	}
	else
	{
		print "We are told it is rh 72, so ia64_rh72\n";
		$TargetDir = ia64_rh72;
	}
}

if ($Config{'archname'} =~ m!solaris!)
{
	$ENV{'PATH'} = ".:/usr/local/sbin:/usr/local/bin:" . $ENV{'PATH'};
    #$ENV{PATH} = '.:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/ucb:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/ucb';
	print "Adjusting component build for solaris\n";
	$TargetDir = sun4x_58;
}

if ($Config{'archname'} =~ m!alpha-dec_osf!)
{
	$ENV{'PATH'} = ".:/usr/local/gcc296:/usr/local/gnu/bin:/usr/local/sbin:/usr/local/bin:" . $ENV{'PATH'};
    #$ENV{PATH} = '/usr/local/gcc296:/usr/local/gnu/bin:/usr/local/bin:.:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/ucb:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/ucb';
	print "Adjusting component build for osf1\n";
	$Compiler = "-compiler=gcc64";
	$TargetDir = alpha_osf1;
}
my $VERSION = " make-gpt-dist 1.0 ";

my $log, $version, $method;
my $TarExec = "tar";
my $GPT_Tarfile = "../../gpt-2.1.tar.gz";
my $GT_Core_Tarfile = "../../globus_core-2.1.tar.gz";
my $GlobusDir  = getcwd();
my $buildInstallGPT;
my $topDir = getcwd();
my $distDir = "static_dir"; 
my $buildSourceBundles;
my $all;
my $all_bundle;
my $all_server, $all_client, $all_sdk;
my $dm_server, $dm_client, $dm_sdk;
my $is_server, $is_client, $is_sdk;
my $rm_server, $rm_client, $rm_sdk;
my $native;
my $os_val = `uname`;
chomp $os_val;
my $put_dev_pkg_in_bin_bundle=0;

print "Building GPT packages for Condor-G\n";
System("printenv");
print "Make-Nmi-Gpt-Dist waking up HERE*************************************\n";
System("pwd; ls");

GetOptions (
	'version' => \$version, 
	'help' => \$help, 
	'compiler=s' => \$Compiler, 
	'tar=s' => \$TarExec, 
	'log=s' => \$log, 
	'all' => \$all,
	'native' => \$native,
	'method' => \$method,
	'gpt-file=s' => \$GPT_Tarfile,
	'globus-core-pkg=s' => \$GT_Core_Tarfile,
	'dist-dir=s' => \$distDir,
	'top-dir=s' => \$topDir

);
if ( $help )	{ help() and exit(0); }
if ( $version )	{ print $VERSION and exit(0); }
if ( $method )	{ $method = "http://www-unix.globus.org/ftppub/"; }
else 			{ $method = "ftp://ftp.globus.org/pub/"; }
if (! $all )	{ askUserQuestions(); }
if ( $log )		{ 
	open(STDOUT, ">$log") or die "Could not open $log: $!";
	open(STDERR, ">&STDOUT");
	select(STDERR); $| = 1;
	select(STDOUT); $| = 1;
}

initializeBuildEnv();
runSpecifiedCommands();

print " ---- make-nmi-gpt-dist Successfully Ended :: ".localtime()." (".time().") ---- \n";

exit(0);


# ===========================================================================
# Subs
# ===========================================================================

# ---------------------------------
# Print Help
# ---------------------------------
sub help {
    print "Usage: make-nmi-gpt-dist [-v --version] [-h --help] [[-l --log] <file>]
Options:
    [-h --help]         Print this message
    [-v --version]      Print out version of gbuild 
    [-c --compiler]     Specify the build flavor (default is gcc32)
    [-t --tar]          Specify GNU Tar executable (default is tar)
    [-l --log <file>]   Log output to <file>
    [-m --method]       Use the ftp protocol to get files (default is http)
    [-a --all]          Select all defaults unless explicity listed on the
                        command line (you will not be prompted)

\n";
}


# ---------------------------------
# Initialize Build Environment
# ---------------------------------
sub initializeBuildEnv {
	printBuildInfo();

	#$ENV{GLOBUS_LOCATION} = "$ENV{PWD}";
	$ENV{TOP_DIR} = "$topDir";
	$distdir = $ENV{DIST_DIR} = "$topDir" . "/" . "$distDir";
}

# ---------------------------------
# Welcome prompt
# ---------------------------------
sub askUserQuestions {
	print "\nFor help, use the --help flag.\n\n";
	print "askUserQuestions:\n";
	$Compiler = promptUser("Flavor Base ", "$Compiler");
	$GlobusDir  = promptUser("Directory you want to build behind ", "$ENV{PWD}");
	$buildInstallGPT  = prompt("Do you want to build and install GPT here? (Y/n) ");
	$buildCondorG = prompt("Do you want to build Condor-G packages? (Y/n) ");

	chdir("$GlobusDir");
}

# ---------------------------------
# Run User Specified Commands
# ---------------------------------
sub runSpecifiedCommands {
	if ( yesNo($buildInstallGPT) or $all )		{ buildInstallGPT(); }
	if ( yesNo($buildCondorG) or $all )	{ buildCondorGPackages(); }

}

# ---------------------------------
# Install GPT
# ---------------------------------
sub buildInstallGPT {
	print " ---- GBUILD :: Installing GPT ---- \n";

	chdir("$GlobusDir");
	if (! -e "$GPT_Tarfile" ) {
		die "can't find $GPT_Tarfile\n";
	}

	System("$TarExec zxvf $GPT_Tarfile");
	System("mkdir -p gpt");
	chdir("$GlobusDir/gpt-2.1");
	$ENV{GPT_LOCATION} = "$GlobusDir/gpt";
	# build_gpt returns a non-zero for some reason so I call it without checking
	system("./build_gpt");
	$ENV{PATH} = "$GlobusDir/gpt/sbin:$ENV{PATH}";
}

# ---------------------------------
# Build Source Bundles
# ---------------------------------
sub buildCondorGPackages {

	print " ---- make-gpt-dist :: Creating Condor-G packages ---- \n";
	chdir("$GlobusDir");
	System("mkdir -p g/condor-g");
	$ENV{GLOBUS_LOCATION} = "$GlobusDir/g/condor-g";
	System("gpt-build $GT_Core_Tarfile ".$Compiler);
	chdir("$GlobusDir/condor_scripts/gpt-data");
	printf("TopDir is $topDir and DistDir is $distDir and globsdir is $GlobusDir\n");
	chdir("$GlobusDir/condor_scripts/gpt-data/condor_base");
	System("gpt-build");

	chdir("$GlobusDir/condor_scripts/gpt-data/condor_base_setup");
	System("gpt-build");

	chdir("$GlobusDir/condor_scripts/gpt-data/condor_base_libs");
	System("gpt-build");

	chdir("$GlobusDir/condor_scripts/gpt-data/condor_config");
	System("gpt-build");

	chdir("$GlobusDir/condor_scripts/gpt-data/condor_submit");
	System("gpt-build");

	chdir("$GlobusDir/condor_scripts/gpt-data/condor_dagman");
	System("gpt-build");

	chdir("$GlobusDir");
	if($native) {
		System("gpt-pkg --rpmlicense=Condor -native -all");
		System("gpt-bundle --native --bindir=./binaries/ \\
        --output=condor-g-6.4-`uname | \\
        tr \"A-Z\" \"a-z\"`-`uname -m`-`uname -r`-bundle.tar.gz  \\
		condor_base condor_base_setup condor_base_libs condor_config \\
		condor_submit condor_dagman ");

	} else {
		System("gpt-pkg --rpmlicense=Condor -all");
		System("gpt-bundle --bindir=./binaries/ \\
        --output=condor-g-6.4-`uname | \\
        tr \"A-Z\" \"a-z\"`-`uname -m`-`uname -r`-bundle.tar.gz  \\
		condor_base condor_base_setup condor_base_libs condor_config \\
		condor_submit condor_dagman ");
	}
}


# ---------------------------------
# RM Client
# ---------------------------------
sub rm_client {
	print " ---- GBUILD :: Building RM Client from source bundle ---- \n";

	chdir("$GlobusDir");
	System("mkdir -p g/rm/client bundles/bin bundles/src");

	if (! -e "$GlobusDir/bundles/src/globus_resource_management_bundle-client-src.tar.gz" ) {
		chdir("$GlobusDir/bundles/src");
		getFile("gt2/2.0/bundles/src/globus_resource_management_bundle-client-src.tar.gz");
	}

	chdir("$GlobusDir/g/rm/client");
	$ENV{GLOBUS_LOCATION} = "$GlobusDir/g/rm/client";

	System("globus-build $GlobusDir/bundles/src/globus_resource_management_bundle-client-src.tar.gz ".$Compiler);
	System("mkdir -p binaries install");
	System("mv *.gz binaries");

	print " ---- GBUILD :: Creating RM Client binary bundle ---- \n";
	if ( $put_dev_pkg_in_bin_bundle )
	{
	    System("gpt-bundle --bindir=./binaries/ \\
		--output=$GlobusDir/bundles/bin/globus_resource_management_bundle-client-`uname | \\
		tr \"A-Z\" \"a-z\"`-`uname -m`-".$Compiler.".tar.gz  \\
		globus_user_env-noflavor_data \\
		globus_core-noflavor_data \\
		globus_common_setup-noflavor_pgm \\
		globus_core_setup-noflavor_pgm \\
		globus_ssl_utils_setup-noflavor_pgm \\
		globus_ssl_utils-".$Compiler."_pgm \\
		globus_common-".$Compiler."_dev \\
		globus_core-".$Compiler."_dev \\
		globus_data_conversion-".$Compiler."_dev \\
		globus_duct_common-".$Compiler."_dev \\
		globus_duct_control-".$Compiler."_dev \\
		globus_duroc_common-".$Compiler."_dev \\
		globus_duroc_control-".$Compiler."_dev \\
		globus_gass_server_ez-".$Compiler."_dev \\
		globus_gass_transfer-".$Compiler."_dev \\
		globus_gram_client-".$Compiler."_dev \\
		globus_gram_protocol-".$Compiler."_dev \\
		globus_gss_assist-".$Compiler."_dev \\
		globus_gssapi_gsi-".$Compiler."_dev \\
		globus_io-".$Compiler."_dev \\
		globus_mp-".$Compiler."_dev \\
		globus_nexus-".$Compiler."_dev \\
		globus_openssl-".$Compiler."_dev \\
		globus_rsl-".$Compiler."_dev \\
		globus_rsl_assist-".$Compiler."_dev \\
		globus_ssl_utils-".$Compiler."_dev \\
		globus_gram_client-".$Compiler."_rtl \\
		globus_gram_client_tools-".$Compiler."_pgm");
	}
	else
	{
	    System("gpt-bundle --bindir=./binaries/ \\
		--output=$GlobusDir/bundles/bin/globus_resource_management_bundle-client-`uname | \\
		tr \"A-Z\" \"a-z\"`-`uname -m`-".$Compiler.".tar.gz  \\
		globus_user_env-noflavor_data \\
		globus_core-noflavor_data \\
		globus_common_setup-noflavor_pgm \\
		globus_core_setup-noflavor_pgm \\
		globus_ssl_utils_setup-noflavor_pgm \\
		globus_ssl_utils-".$Compiler."_pgm \\
		globus_gram_client-".$Compiler."_rtl \\
		globus_gram_client_tools-".$Compiler."_pgm");
	}

	print " ---- GBUILD :: Installing RM Client binary bundle ---- \n";
	$ENV{GLOBUS_LOCATION} = "$GlobusDir/g/rm/client/install";
	System("globus-install $GlobusDir/bundles/bin/globus_resource_management_bundle-client-`uname | \\
		tr \"A-Z\" \"a-z\"`-`uname -m`-".$Compiler.".tar.gz"); 

	# Created to provide easy ability to change G_L to this directory for testing purposes
	open (FD, ">setGL.csh");
	print FD "setenv GLOBUS_LOCATION \'$GlobusDir/g/rm/client/install\'";
	close FD;
	open (FD, ">setGL.sh");
	print FD "export GLOBUS_LOCATION=\'$GlobusDir/g/rm/client/install\'";
	close FD;
}

# ---------------------------------
# Util Subs
# ---------------------------------

sub promptUser {
	local($promptString,$defaultValue) = @_;

	if ($defaultValue) {
		print $promptString, "[", $defaultValue, "]: ";
	} 
	else {
		print $promptString, ": ";
	}

	$| = 1;               # force a flush after our print
	$_ = <STDIN>;         # get the input from STDIN (presumably the keyboard)

	chomp;

	if ("$defaultValue") {
		return $_ ? $_ : $defaultValue;    # return $_ if it has a value
	} 
	else {
		return $_;
	}
}

sub prompt {
	print @_;
	$| = 1;               # force a flush after our print
	$_ = <STDIN>;         # get the input from STDIN (presumably the keyboard)
	chomp;
	return $_;
}

sub System 
{
	my @args = @_;
	my $rc = 0xffff & system @args;

	printf "system(%s) returned %#04x: ", @args, $rc;

	if ($rc == 0) 
	{
		print "ran with normal exit\n";
		return $rc;
	}
	elsif ($rc == 0xff00) 
	{
		print "command failed: $!\n";
		return $rc;
	}
	elsif (($rc & 0xff) == 0) 
	{
		$rc >>= 8;
		print "ran with non-zero exit status $rc\n";
		return $rc;
	}
	else 
	{
		print "ran with ";
		if ($rc &   0x80) 
		{
			$rc &= ~0x80;
			print "coredump from ";
			return $rc;
		}
		print "signal $rc\n"
	}

}

sub yesNo {
	# print "Incoming: @_ \n";
	if ("@_" =~ /^y$/i or "@_" =~ /^yes$/i or "@_" =~ /^$/ ) { 
		# print "YES\n";
		return 1; 
	}
	elsif ("@_" =~ /^n$/i or "@_" =~ /^no$/i) { 
		# print "NO\n";
		return 0; 
	}
	else { 
		# print "FOO\n";  
		return 0; 
	}
} 

sub getFile {
	my $file = $_[0];
	my $wget = `which wget`;
	chomp $wget;
	if (-x "$wget") { System("wget $method$file"); }
	else { 
		print "Could not find utility wget to download file.\n"; 
		print "You need to download the necessary bundles and/or gpt\n";
		print "from the following location:\n";
		print "http://www-unix.globus.org/ftppub/gt2/2.0\n"; 
		exit;	
	}
}

sub printBuildInfo {
	my $osName = `uname`;
	chomp $osName;
	my $osVersion = `uname -r`;
	chomp $osVersion;
	my $hostname = `hostname`;
	chomp $hostname;
	my $cpuArch = `uname -m`;
	chomp $cpuArch;
	print " ---- GBUILD Start :: ".$osName.":".$osVersion.":".$cpuArch.":".$hostname.":".$Compiler.":".localtime()." (".time().") ---- \n";
}
