#!/usr/bin/perl 
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/usr/lpp/bosinst/samples/AE/AE/ManageALFile.pl 1.1 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2008,2009 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 

# @(#)26        1.1  src/bos/usr/lpp/bosinst/samples/AE/AE/ManageALFile.pl, bosinst, bos720 3/29/09 15:19:59

#----------------------include--------------------#
use XML::LibXML;
#----------------------include--------------------#
#
## This script - ActiveVM is executed by AE service
## and reads parameters from ovf-env.xml or *.ap.
## This script is called with three command line 
## arguments. The first is the AE path, the second
## is the resource name, and the third is the 
## config name. For example, a valid call to this
## would be:
##   perl ActivateVM /opt/IBM/AE SUSE_V10 ConfigNET
#
#-------------------main process------------------#

# get parameters
$AEPATH = "/opt/IBM/AE";
$ACTION = $ARGV[0];
$AL = $ARGV[1];

# AE's subdirectories
$APPATH="${AEPATH}/AP";
$ALPATH="${AEPATH}/AL";

$MASTERAL = "${ALPATH}/master.al";
$TEMPLATEMASTERAL = "${ALPATH}/master.template";

print "Action == $ACTION\n";
print "AL == $AL\n";
if ( $ACTION eq "-a" )
{
    addResourcesToMasterAlFile();
}
if ( $ACTION eq "-r" )
{
    removeResourcesFromMasterAlFile();
    if(! &hasRsrcNode())
    {
	system("rm -rf ${MASTERAL}*");
    }
}
#-------------------main process------------------#

#--------------subfunction definition-------------#


# get resource name, configuration name and script path from AL file
sub addResourcesToMasterAlFile
{

    if( ! -e $MASTERAL )
    {
	system("cp ${TEMPLATEMASTERAL} ${MASTERAL}");    
    }

    my $alDoc = openXMLFile($AL);
    my $masterALDoc = openXMLFile($MASTERAL);
    my %alParam = ();

    my $resrcName = "";

    my @resourceNodes = $alDoc->getElementsByTagName("software-resource");
    my $virtualImageTag = $masterALDoc->getElementsByTagName("virtual-image")->[0];
    foreach my $resourceNode (@resourceNodes)
    {
	copySubTree($resourceNode, $virtualImageTag);
    }

    saveMasterALFile($masterALDoc);
    return;
}

sub removeResourcesFromMasterAlFile
{
    my $alDoc = openXMLFile($AL);
    my $masterALDoc = openXMLFile($MASTERAL);
    my $newMasterALDoc = openXMLFile($TEMPLATEMASTERAL);
    my %alParam = ();

    my $resrcName = "";
    my @resrcNameList = ();

    my @resourceNodes = $alDoc->getElementsByTagName("software-resource");
    foreach my $resourceNode (@resourceNodes)
    {
	$resrcName = $resourceNode->getAttributeNode("name")->getValue();
	push @resrcNameList, $resrcName;
    }

    my $newMasterLogVirtualImageElement = $newMasterALDoc->getElementsByTagName("virtual-image")->[0];


    @resourceNodes = $masterALDoc->getElementsByTagName("software-resource");

    foreach my $resourceNode (@resourceNodes)
    {
	my $skip = 0;
	my $masterALDocResName;
	foreach  $resrcName (@resrcNameList)
	{
	    $masterALDocResName = $resourceNode->getAttributeNode("name")->getValue();
	    if( $resrcName eq $masterALDocResName )
	    {
		$skip = 1;
	    }
	}
	if($skip == 0)
	{
	    copySubTree($resourceNode, $newMasterLogVirtualImageElement);
	}
    }

    saveMasterALFile($newMasterALDoc);
    return;
}

sub saveMasterALFile
{
    my ($masterAlDoc)=@_;
    my $flag = 0;
    system("mv -f ${MASTERAL} ${MASTERAL}.old");
    $masterAlDoc->toFile($MASTERAL, 1);
}

sub copySubTree
{
    my ($sourcenode, $destnode) = @_;
    my $copy_node =  $sourcenode->cloneNode(1);
    if ( $sourcenode->ownerDocument() ne $destnode->ownerDocument() ) 
    {
	$copy_node->setOwnerDocument( $destnode->ownerDocument() );
    }
    my $rsrcName=$copy_node->getAttributeNode("name")->getValue();
    my @rsrcNodes=$destnode->getElementsByTagName("software-resource");
    my $containRsrcNode=0;
    foreach my $rsrcNode (@rsrcNodes)
    {
	if($rsrcNode->getAttributeNode("name")->getValue ne "$rsrcName")
	{
	    next;
	}
	$containRsrcNode=1;
	my @copy_nodeChilds=$copy_node->childNodes();
	my @rsrcNodeChilds=$rsrcNode->childNodes();
	my $iLength=$#copy_nodeChilds;
	my $jLength=$#rsrcNodeChilds;
	for(my $i=0;$i<=$iLength;$i++)
	{
	    my $containConfNode=0;
	    my $confName=$copy_nodeChilds[$i]->nodeName();
	    if("$confName" ne "configuration")
	    {
		next;
	    }
	    my $attrName=$copy_nodeChilds[$i]->getAttributeNode("name")->getValue();
	    for(my $j=0;$j<=$jLength;$j++)
	    {
		my $destConfName=$rsrcNodeChilds[$j]->nodeName();
		if("$destConfName" ne "configuration")
		{
		    next;
		}
		my $destAttrName=$rsrcNodeChilds[$j]->getAttributeNode("name")->getValue();
		if( "$attrName" eq "$destAttrName")
		{
		    $containConfNode=1;
		    last;
		}
	    }
	    if( "$containConfNode" != 1)
	    {
		$rsrcNode->appendChild($copy_nodeChilds[$i]);
	    }
	}
    }

    if( $containRsrcNode != 1)
    {
	$destnode->appendChild($copy_node);
    }
    return $copy_node;
}


sub openXMLFile
{
    my($fpath)=@_;
    my $parser=new XML::LibXML();
    my $ldoc;

    $ldoc=eval
    {
	$parser->parse_file($fpath);
    };

    $ldoc || die "can not open file  " . $fpath . "\n";
    return $ldoc;
}

sub hasRsrcNode()
{
    my $masterDoc=openXMLFile($MASTERAL);
    my @rsrcNodes=$masterDoc->getElementsByTagName("software-resource");
    if($#rsrcNodes >= 0)
    {
	return 1;
    }
    else
    {
	return 0;
    }
}
