#!/usr/local/bin/perl
# 
# $Header: rac_upgrade.pl 27-aug-2005.20:19:45 xuliu Exp $
#
# rac_upgrade.pl
# 
# Copyright (c) 2005, Oracle. All rights reserved.  
#
#    NAME
#      rac_upgrade.pl - upgrade cluster & host targets from 10.1 to 10.2 format
#        Usage: rac_upgrade.pl [-tgt_home] <home> 
#
#    DESCRIPTION
#      <short description of component this file declares/defines>
#
#    NOTES
#      <other useful comments, qualifications, etc.>
#
#    MODIFIED   (MM/DD/YY)
#    xuliu       08/27/05 - xuliu_bug-4536783
#    xuliu       08/17/05 - Creation
# 
use strict;
require "semd_common.pl";

my $tgtXmlPath = $ARGV[0];
if ( $tgtXmlPath eq "-tgt_home")
{
    $tgtXmlPath = $ARGV[1];
}

$tgtXmlPath = "${tgtXmlPath}/sysman/emd/targets.xml";

my ($sLns, $eLns, @tgts) = getTargets($tgtXmlPath);

# Assumption: there is at most ONE host and ONE cluster target in the targets.xml
my $hstIndex = -1;
my $clsIndex = -1;

for (my $i=0; $i<@tgts; $i++)
{
    my $type = getTargetType($tgts[$i]);
    if ( uc($type) eq  "CLUSTER")
    {
        $clsIndex = $i;
        last if ($hstIndex >= 0);
    }
    elsif (uc($type) eq "HOST")
    {
        $hstIndex = $i;
        last if ($clsIndex >= 0);
    }
}

my ($tmp, $crsHome) = getClusterName();

if ($clsIndex >= 0)
{
    _DEBUG("CLUSTER target found as the " . $clsIndex . "th target: $tgts[$clsIndex]");    
}
else
{
    _DEBUG("CLUSTER target NOT found.");
}

if ($hstIndex >= 0)
{
    _DEBUG("HOST target found as the " . $hstIndex . "th target: $tgts[$hstIndex]");    
}
else
{
    _DEBUG("HOST target NOT found.");
}


# proceed only if cluster and host targets exists
if ($hstIndex >= 0 && $clsIndex >= 0)
{
    my $clsName = getTargetName($tgts[$clsIndex]);
    my $OHProp = "    <Property NAME=\"OracleHome\" VALUE=\"$crsHome\"/>\n";
    
    _DEBUG("CLUSTER target name = $clsName");
    _DEBUG("CRS_HOME = $crsHome");
    
    if ($clsName ne "")
    { 
        if ($crsHome ne "")
        {
            # add the OracleHome property to cluster target
            my $tgtCls = $tgts[$clsIndex];
            $tgtCls =~ s/\n/ /g;

            my $trailTag = 1;
            if ($tgts[$clsIndex] =~ /\/>\s*$/)
            {
               _DEBUG("Cluster target ends with '/>'");
               $trailTag = 0;
            } 
            
            if (!$trailTag)
            {
               $tgts[$clsIndex] =~ s/\/>[\n\s]*$/>\n/s;
               $tgts[$clsIndex] .= "    " . $OHProp;
               $tgts[$clsIndex] .= "    </Target>\n";
            }
            else
            {
                if ($tgtCls !~ /<Property\s+.*?NAME\s*=\s*\"OracleHome\".*?\/>/i)
                {
                    $tgts[$clsIndex] =~ s/<\/Target/${OHProp}    <\/Target/si;
                } 
                else
                {
                    _DEBUG("OracleHome property already exists for the cluster target...cluster target skipped: $&");
                }    
            }
        }    
        else
        {
            _DEBUG("CRS_HOME is not found on the host...cluster target skipped.");
        }    
        
        _DEBUG ("Upgraded cluster target=\n$tgts[$clsIndex]");    
    
        # now host target
        my $assoc = 
            "<AssocTargetInstance ASSOCIATION_NAME=\"cluster_instance\" ASSOC_TARGET_TYPE=\"cluster\" ASSOC_TARGET_NAME=\"$clsName\"/>\n    ";
        
        my $tgtHst = $tgts[$hstIndex];
        $tgtHst =~ s/\n/ /g;
        
        if ($tgtHst =~ /<MemberOf\s+(.*?)\/>/i)
        {
            my $mem = $1;
            
            if ( $mem =~ /NAME\s*=\s*\"${clsName}\"/i && $mem =~ /TYPE\s*=\s*\"cluster\"/i)
            {
                # let's see if the assoc already exists
                if ($tgtHst !~ /<AssocTargetInstance\s+(.*?)\/>/i)
                {
                    $tgts[$hstIndex] =~ s/<CompositeMembership/${assoc}<CompositeMembership/si;
                }
                else
                {
                    _DEBUG("AssocTargetInstance already exists for the host target...host target skipped: $&"); 
                }    
            }
            else
            {
                _DEBUG("MemberOf exists for the host target but it's not associated with cluster '$clsName' ... host target skipped: $&");
            }    
        }
        else
        {
            _DEBUG("No MemberOf is found in the host target...host target skipped.");
        }
        
        _DEBUG("Upgraded host target=\n$tgts[$hstIndex]");

        open (OUTFILE, ">$tgtXmlPath") or die "Failed to open $tgtXmlPath for write\n";
        
        print OUTFILE $sLns;
        for (my $i=0; $i<@tgts; $i++)
        {
            print OUTFILE $tgts[$i];
        }
        print OUTFILE $eLns;
        
        close (OUTFILE);
        
    }
    else
    {
        _DEBUG("Cannot identify cluster target name");
    }
}    

sub getTargets
{
   my $targetXml = $_[0];
   my @rstTgts;
   
   my ($headLns, $tailLns);
    
   if (open(TGTXML, "<$targetXml"))
   {
      my @lns = <TGTXML>;
      close(TGTXML);

      my $bigL = join '', @lns;
      
      # get rid of comments
      $bigL =~ s/<!--.*?-->//g;

      my @tgts = split /<Target[\n\s]+/i, $bigL;
      
      my $num = @tgts;
      
      my @twoParts = split /<\/Targets/i, $tgts[$num - 1];
      
      $tgts[$num - 1] = $twoParts[0];
      if ($twoParts[1] ne "")
      {
        $tailLns = "</Targets" . $twoParts[1];
      }  

      $headLns = $tgts[0];
      
      foreach (my $i = 1; $i < $num; $i++)
      {
         push @rstTgts, "<Target " . $tgts[$i];
      }
   }
   else
   {
        die("Failed to open $targetXml for read");
   }

   ($headLns, $tailLns, @rstTgts);
 }   

sub getTargetName
{
    getTargetAttr($_[0], "name");
}

sub getTargetType
{
    getTargetAttr($_[0], "type");
}

sub getTargetAttr
{
    my $tgt = $_[0];
    my $attr = $_[1];
    my $val;
    
    $tgt =~ s/\n/ /g;
    
    if ($tgt =~ /<target\s+.*?${attr}\s*=\s*\"(.*?)\".*?>/i)
    {
        $val = $1;
    }
    
    $val;
}

sub _DEBUG
{
    print "INFO: $_[0]\n";
}