#!/usr/bin/perl
BEGIN
{
    $::XCATROOT =
        $ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
      : -d '/opt/xcat'   ? '/opt/xcat'
      : '/usr';
}
use lib "$::XCATROOT/lib/perl";
use strict;

use Getopt::Long;
require xCAT::MsgUtils;
require xCAT::DSHCLI;
require xCAT::Client;

use xCAT::Utils;
use File::Basename;

$::XCATROOT = "/opt/xcat";
my $os = "";
my $profile = "";
my $interface = "";
my $version;
my $drivers = "";
my $otherInterfaces = "";
my $kernel = "";
my @oses; # available OSes.
my @profiles; # available profiles
my $profDir; # root where you do ./genimage from
my $help;
my $match = 0;
my $imagename;
my $arch;
my $permission;
my $rootlimit;
my $tmplimit;
my $krpmver;
my $kerneldir;
my $mode;
my $interactive;

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

=head3 print_usage   - usage message

=cut

#-----------------------------------------------------------------------------
sub print_usage
{
    print "Usage:\n";
    print "    genimage\n\n";
    print '    genimage  -o <osver> [-a <arch>] -p <profile> -i <nodebootif> -n <nodenetdrivers> [-r <otherifaces>] [-k <kernelver>] [-g <krpmver>] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>] [--interactive]'."\n\n";
    print '    genimage [-o <osver>] [-a <arch>] [-p <profile>] [-i <nodebootif>] [-n <nodenetdrivers>] [-r <otherifaces>] [-k <kernelver>] [-g <krpmver>] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>] [--interactive] <imagename>'."\n\n";
    print "      --permission is used for statelite only\n";
    print "      -g is used for SLES only\n\n";
    print "      -m is used for urbuntu, debian and fedora12 only\n\n";
    print "Examples:\n";
    print "    genimage\n";
    print "    genimage --interactive\n";
    print "    genimage -i eth0 -n tg3 -o sles11 -p compute\n";
    print "    genimage -i eth0 -r eth1,eth2 -n tg3,bnx2 -o centos5.1 -p compute --interactive\n";
    print "    genimage -i eth0 -n tg3,bnx2 -o sles11 -p compute\n";
    print "    genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n";
    print "    genimage -i eth0 -n tg3 --interactive myimagename\n";
    print "    genimage myimagename\n";
}

if (!GetOptions(
	 'a=s' => \$arch,
	 'p=s' => \$profile,
	 'o=s' => \$os,
	 'n=s' => \$drivers,
	 'i=s' => \$interface,
	 'r=s' => \$otherInterfaces,
	 'l=s' => \$rootlimit,
	 't=s' => \$tmplimit,
	 'k=s' => \$kernel,
	 'g=s' => \$krpmver,
	 'm=s' => \$mode,
	 'permission=s' => \$permission,
	 'kerneldir=s' => \$kerneldir, 
         'interactive' => \$interactive,  
	 'h|help' => \$help,
	 'v|version' => \$version,
)) {
   &print_usage;
   exit 1;
}

if($help){
    &print_usage;
    exit 0;
}

if ($version){
    my $version = xCAT::Utils->Version();
    xCAT::MsgUtils->message("N", $version);
    exit 0;

}
if (@ARGV > 0) {
    $imagename=$ARGV[0];
}

if ((!$imagename) && (!$profile) && (!$os) && (!$arch)) {
    my $tmpimgs=`lsdef -t osimage -w provmethod=~'/statelite|netboot/' |cut -d' ' -f1`;
    if ($? == 0) {
	if (($tmpimgs) && ($tmpimgs !~ /^Could/)) { #Could is returned when the osimage table is empty
	    my @images=split('\n', $tmpimgs);
	    print "Do you want to re-genarate an existing image from the osimage table? ";
	    print "[y/n] ";
	    my $conf = <stdin>;
	    chomp($conf);
	    if($conf ne "" && $conf !~/N|n|[Nn][Oo]/) {
		$match = 0;
		while(1){
		    print "Available images: \n";
		    foreach(sort @images){
			print  "   $_\n";
		    } 
		    # default is the first image cause in many cases
		    print "Which image do you want to re-generate? [";
		    print $images[0];
		    print "] ";
		    
		    my $img = <stdin>;
		    chomp($img);
		    if($img eq ""){
			$imagename = $images[0];
			last;
		    }
		    foreach(@images){
			if($img eq $_){
			    $imagename=$img;
			    $match = 1;
			}	
		    }
		    if ($match) {
			last;
		    } else {
			print "$img is not found in the osimage table.\n";
		    }
		}
	    } 
	}
    }
}


# get the install directory
my $installdir = `gettab key=installdir site.value`;
chomp($installdir);
# lots of error checking to make sure it exists.
if($installdir eq ''){
    print "Could not get install directory from site table.  Assuming your OSes are stored in '/install'\n";
    $installdir = "/install";
}
    
unless(-d $installdir){
    print "The directory where your OS distributions resides: $installdir does not exist.  Please check site table\n";
    exit 1;	
}

if ((!$imagename) && (!$os)){
    my @dircontents = `ls $installdir`;
    chomp(@dircontents);
    foreach (@dircontents) {
	if($_ =~ /(rhel|fedora|sl|centos|suse)/){
	    push @oses,$_;
	}
    } 
    
    if($#oses eq -1){
	print "There are no OS repositories in $installdir.  Please run copycds for the OS first.\n";
	exit 1;
    }
    
    # now they have the OSes, make sure they select one that is available
    $match = 0;
    while(1){
	print "Available OSes: \n";
	foreach(@oses){
	    print  "   $_\n";
	}
	# default is the first OS cause in many cases, they'll only have 1.
	print "Which OS do you want to build a image for? [";
	print $oses[0] ;
	print "] ";
	
	$os = <stdin>;
	chomp($os);
	if($os eq ""){
	    $os = $oses[0];
	    last;
	}
	foreach(@oses){
	    if($os eq $_){
		$match = 1;
	    }	
	}
	
	if($match){
	    last;
	}else{
	    print "$os is not found in '$installdir'\n";
	}
    }
    
    chomp($os);
}
print "  OS: $os\n";



### Get the Profile ####
my $osfamily = $os;
$osfamily  =~ s/\d+//g;
$osfamily  =~ s/\.//g;
if($osfamily =~ /rh/){
  $osfamily = "rh";
}

# OS version on s390x can contain 'sp', e.g. sles11sp1
# If the $osfamily contains 'sles' and 'sp', the $osfamily = sles
if ($osfamily =~ /sles/ && $osfamily =~ /sp/) {
    $osfamily = "sles";
}

#print "OSfamily: $osfamily\n";
$profDir = "$::XCATROOT/share/xcat/netboot/$osfamily";
unless(-d $profDir){
    print "Unable to find genimage script in $profDir\n";
    exit 1;
}

if ((!$imagename) && (!$profile)){
    my $profDir2 = "$installdir/custom/netboot/$osfamily";
    my @proList = `ls $profDir/*.pkglist`;
    if (-d $profDir2) {
	@proList = (@proList, `ls $profDir2/*.pkglist`);
    }
    my %seen = ();
    foreach (@proList) {
	my $f = basename($_);
	$f =~ s/([^\.]*).*/$1/;
	chomp($f);
	$seen{$f}++;
    } 
    @profiles = sort keys %seen;
    if($#profiles eq -1){
	print "There are no profiles in $::XCATROOT/share/xcat/netboot/$osfamily.\n";
	exit 1;
    }
    $match = 0;
    while(1){
	print "Available Profiles for $os: \n";
	foreach(@profiles){
	    print "   $_\n"; 
	}
	# default is the first OS cause in many cases, they'll only have 1.
	print "Which profile do you want to use for $os?  [";
	print "$profiles[0] ";
	print "] ";
	
	$profile = <stdin>;
	chomp($profile);
	if($profile eq ""){
	    $profile = $profiles[0];
	    last;
	}
	foreach(@profiles){
	    if($profile eq $_){
		$match = 1;
	    }	
	}
	if($match eq 1){
	    last;
	}
    }
}
print  "  Profile: $profile\n";

# get the interface
if ((!$imagename) && (!$interface)){
    while(1){
	print "Which network interface do you want the image to boot from? [";
	print "eth0";
	print "] ";
	$interface = <stdin>;
	chomp($interface);
	if($interface eq ""){
	    $interface = "eth0";
	    last;
	}else{
	    print "You want your stateless machines to boot off of ";
	    print "$interface";
	    print "? ";
	    print "[Y/n] ";
	    my $conf = <stdin>;
	    chomp($conf);
	    if($conf eq ""){
		last;
	    }
	    if($conf =~ /Y|y|[Yy][Ee][Ss]/){
		last;
	    }	
	}
    }
}
print "  Interface: $interface\n";

    

print "Generating image: \n";
my @arg;
if ($imagename) {
    push @arg, "$imagename";
}

if ($interface) {
    push @arg, "-i";
    push @arg, "$interface";
}
if ($drivers) {
    push @arg, "-n";
    push @arg, "$drivers";
}
if ($os) {
    push @arg, "-o";
    push @arg, "$os";
}
if ($profile) {
    push @arg, "-p";
    push @arg, "$profile";
}
if ($arch) {
    push @arg, "-a";
    push @arg, "$arch";
}

if ($kernel) {
    push @arg, "-k";
    push @arg, "$kernel";
}

if($otherInterfaces){
    push @arg, "-r";
    push @arg, "$otherInterfaces";
}

if ($permission) {
    push @arg, "--permission";
    push @arg, "$permission";
}

if ($rootlimit) {
    push @arg, "-l";
    push @arg, "$rootlimit";
}

if($tmplimit) {
    push @arg, "-t";
    push @arg, "$tmplimit";
}

if ($krpmver) {
    push @arg, "-g";
    push @arg, "$krpmver";
}

if ($mode) {
    push @arg, "-m";
    push @arg, "$mode";
}

if ($kerneldir) {
    push @arg, "--kerneldir";
    push @arg, "$kerneldir";
}

my $tempfile="/tmp/xcat_genimage.$$";
push @arg, "--tempfile"; #this is the file that contains the output
push @arg, "$tempfile";

if ($interactive) {
    push @arg, "--interactive";
}

my $cmdref;
push (@{$cmdref->{arg}}, @arg);
$cmdref->{command}->[0] = "genimage";   

if (!$interactive) {
    xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
    exit $xCAT::Client::EXITCODE;
} else {
    #when in interactive mode, first call genimage.pm get info from DB, 
    xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);

    #then call the specific genimage under /opt/xcat/share...
    if (-f $tempfile) {
	my $cmdname;
	#read the command name
	open(FILE1, "<$tempfile");
	my @output = <FILE1>;
 	if (@output >0) {
	    $cmdname=$output[0];
	} else {
	    close FILE1;
	    return 1;
	}
	close FILE1;

	# run the specific genimage command
	#print "cmdname=$cmdname\n";
	system("$cmdname");

	#then call genimage.pm to save the DB
	my @arg1;
	push @arg1, $tempfile;
	my $request;
	push (@{$request->{arg}}, @arg1);
	$request->{command}->[0] = "saveimgdata";  
	xCAT::Client::submit_request($request, \&xCAT::Client::handle_response);
	exit $xCAT::Client::EXITCODE;
    } else {
	exit 1;
    }
}
    
