#!/usr/bin/perl5.8.8 
use File::Copy;
use Data::Dumper;
use File::Path;
# It is use to get current date and time.
use Time::HiRes qw(gettimeofday);
use POSIX "strftime";
use Time::Local;

# variables
my $baseFolder = "/usr/local/megha";

if (@ARGV != 5  ) {
	print "Usage: perl svpRawConfDataProcessor.pl <inputp zip fileName> <siteName> <SVP IP Address> <startTime> <output zip fileName>\n\n";
	logMsg("Usage: perl svpRawConfDataProcessor.pl <inputp zip fileName> <siteName> <SVP IP Address> <startTime> <output zip fileName>\n\n");
	exit 1;
}

# collecting 1st argument which is the absolute path of zip file name to be processed
my $confZipFile = $ARGV[0];  # '/<path>/Conf20130611_011500_admin_192.168.1.12_SVP.zip'

# collecting siteName from 2nd argument
my $siteName = $ARGV[1]; 
$siteName = substr($siteName, index($siteName,'=')+1);

# collecting probeServer Name/IP from 3rd argument
my $svpIP = $ARGV[2]; 
$svpIP = substr($svpIP, index($svpIP,'=')+1);

# collecting startTime from 4th argument
my $startTime = $ARGV[3];
$startTime = substr($startTime, index($startTime,'=')+1);

# collecting o/p filename to which the processed file must be kept
my $finalFileName = $ARGV[4];  

my $zipFileName = substr($confZipFile, rindex($confZipFile, '/')+1 ); # extracting only filename i.e /usr/local/ab.zip => ab.zip
$zipFileName = substr ($zipFileName, 0, rindex ($zipFileName, '.'));   # extracting filename ab.zip => ab

logMsg("startTime: $startTime\nsiteName:$siteName\nsvpIP:$svpIP\n");

# create location where extracted files should be kept
my $tmpDataDir = "$baseFolder/temp/svp/extract/conf/".$zipFileName."/";
mkpath $tmpDataDir;
my $retValUnzip = system( "unzip -o $confZipFile -d $tmpDataDir" ); # extracting zip file to same location in tmp dir

if ($retValUnzip)
{
	logMsg("Error: UnZipping raw conf file failed");
	print "unzipping failed\n";
	exit 1;
}

opendir(DIR, $tmpDataDir ); 
my @tmpDirFilesList = readdir(DIR);
closedir(DIR);


# Snapshot file creation
mkpath "$baseFolder/temp/svp/data/conf/";
my $snapshotFileName = "$baseFolder/temp/svp/data/conf/Conf_".$startTime."_snapshot_".$siteName."_".$svpIP."_SVP.txt";
open (SNAPSHOT, ">$snapshotFileName");
my $SnapshotFile = SNAPSHOT;


my $topLevelFolder = "";

# variables for R:raidStorage entity need to be global
my $serialNumber = "";
my $modelUspv = "";
my $microVer = $modelName = "";
my $storageCacheSize = "";
my $noOfPG = $noOfLdev = $noOfPoolVols = $noOfPhyLdev = $numberOfPools = 0;  # $noOfPoolVols are volumes used to create pools, vols that belong to PG
my $totalPgCapacity = $totalAllocCapacity = $totalUnAllocCapacity = 0; # all phy 
my $totalPhySystemCapacity = 0;
my $totalVirtualCapacity = 0; # all virtual
my %allocatedLdevMap;  # phy ldev mapped to hosts directly
my %allocatedVVOlMap;  # v vol mapped to hosts
my %unAllocatedLdevMap;	# phy ldev neither mapped to hosts nor used to create pool or available for creating pool
my %unAllocatedVVolMap; # v vol created form pool but not mapped to hosts
my %ldevPoolMap;  # phy ldev used to create pool
my %pgToLdevMapRef;   # variable for aggregation of data at pg level
my %poolToVVOLMapRef; # variable for aggregation of data at pool level
my %exPgToLdevMap;  # map for holding ExPG to Ldev map list
my %concatenatedPGMap = (); # map for holding names of Concatenated PGs - map = { "<PGName>" => "<ConcatenatedPGName>"   eg: {1-12 =>  1-12[1-23 1-24]}
my %poolToTierCountMap = ();
my $totalFreePhyCapacity = 0;
my %ldevWWNMap = ();
my %hgIdPortWWNMap = ();
my %ownerMap = (); 
my %ownerMapping = (); # store mapping between owner => port, owner => pool, owner => PG, owner => MPB.

# dumping metadata into the snapshot file
dumpMetaData($SnapshotFile);

# write timestamp
print SNAPSHOT "t:$startTime\n\n";

# code to read shared resources from perf- eg: mp
# till perf_svpIP.lck file is present, dnt process anything
until (-e "$baseFolder/db/probe/raw/perf_$svpIP.lck"){
		
	open (PerfLock, ">$baseFolder/db/probe/raw/perf_$svpIP.lck");
	logMsg("reading resources from perf sharing.");
	logMsg("file: $baseFolder/db/probe/raw/perfShare_$svpIP.txt ");
		
	if (-e "$baseFolder/db/probe/raw/perfShare_$svpIP.txt") {
		
		logMsg("file: $baseFolder/db/probe/raw/perfShare_$svpIP.txt exists");
		open (PerfShareFH, "<$baseFolder/db/probe/raw/perfShare_$svpIP.txt");
		while($currLine = readline(PerfShareFH)) {
		
			if ($currLine =~ m/^[Rra].*$/){   # if line has a Resource(R:), Attribute(a:), or relation(r:) dump it in snapshot file
				print $SnapshotFile "$currLine";
			
			}
			elsif ($currLine =~ m/^starts=.*/){
				
				next;
			}
			elsif ($currLine =~ m/^[0-9]+[-][E][-0-9]+.*/) {
				
				# added code for reading ExPG to Ldev List data, to be able to aggregate Ldev Capacity 
				# for total Cap. of ExPG as we don't get that in raidcom output
				
				my @tArray = split ('=', $currLine);
				my $exPgName = $tArray[0];
				my $ldevArrayStr = $tArray[1];
				
				my @ldevArray = split (',', $ldevArrayStr);
		
				foreach my $ldevName (@ldevArray) {
					
					$exPgToLdevMap{$exPgName}->{trim($ldevName)} = "";
				}
			}
			elsif ($currLine =~ m/^ends/) {
			
				last;
			}
		}
		
		print $SnapshotFile "\n";
		close (ConfShareFH);
	}
	else {
		logMsg("perf sharing file doesn't exist.");
	}
	
	close(PerfLock);
			
	# deleting lock file
	unlink("$baseFolder/db/probe/raw/perf_$svpIP.lck");
	last;
}


# iterating through raw conf files and dumping data into Snapshot file
foreach my $tmpFile(@tmpDirFilesList) {
	
	if ($tmpFile =~ m/^\./) {   # to skip hidden files starting with "."
		next;
	}
	
	# traversing tmp dir to find perf folder with data (if file is a dir & contains date in its name)
	if( -d $tmpDataDir."/".$tmpFile && $tmpDataDir."/".$tmpFile =~ m/^Conf.*/ ) { 
	
		opendir(DIR, "$tmpDataDir"."/"."$tmpFile" ); 
		my @tmpFileList = readdir(DIR);
		closedir(DIR);
		print "tmpDataDir: $tmpDataDir\n";
		print "tmpFile: $tmpFile\nfrom here\n";

		my $dateDir = "";
		foreach my $fileVar (@tmpFileList) {
			if( -d $tmpDataDir."/".$tmpFile."/$fileVar" && $fileVar =~ m/^([0-9_]+)$/ ) {
				$dateDir = $fileVar;		
				last;
			}
		}

		$topLevelFolder = "$tmpDataDir"."$tmpFile"."/".$dateDir; # date level folder inside the zip file
		print "topLevelFolder:  $topLevelFolder\n\n";

		opendir(DIR, "$topLevelFolder" ); 	
		my @tmpDateDirFileList = readdir(DIR);
		closedir(DIR);
			
		# this part is used to fetch Storage Serial Number and Micro-Version
		# creating half of storage resource here and other half after collecting all other entities and aggregating
		
		open (RESOURCEFILE, "$topLevelFolder/svpStorageConf.txt");
		
		while (my $line = readline(RESOURCEFILE)) {
			
			if ( $line =~ m/^No[ ]+Group[ ]+Hostname[ ]+HORCM_ver[ ]+Uid[ ]+Serial#[ ]+Micro_ver[ ]+Cache\(MB\)/ ) {  
				next;
			}
			else {
				my @tmpArr = split (' ', $line);
				$serialNumber = $tmpArr[5];     
				$microVer =  $tmpArr[6]; 
				$storageCacheSize =  $tmpArr[7]; 
				
				# extracting microcode to check if storage model is uspv or not
				my @tArr1 = split ('-',$microVer);   # eg: microcode = 70-05-11/00
				my $microVerNew = $tArr1[0].$tArr1[1].$tArr1[2];
				@tArr1 = split ('/',$microVerNew);
				$microVerNew = $tArr1[0].$tArr1[1];
				
				if ( $microVerNew >= 60000000 && $microVerNew < 70000000 ) {
					$modelUspv = "true";
				}
				
				# this will make sure other entries are not treated as Storage resources as they are only Resource Groups
				last;
			}
		}
		close (RESOURCEFILE);
		########### add the part similar to this one reading svpResourceConf, for reading microVersion of storage from svpStorageConf
		# Storage conf over. now process rest of the files	
			
			
		foreach my $confFile (@tmpDateDirFileList) {
			
			if ($confFile =~ m/^\./) {   # to skip hidden files starting with "."
				next;
			}
			
			if($confFile =~ m/svpHGConf/) {
			
				processHGConf($confFile);
			}
			elsif ($confFile =~ m/svpClprConf/) { 
			
				processClprConf($confFile);
			}
			elsif ($confFile =~ m/svpExGroupConf/) { 
				
				next;	# will process ldev, pg/exPg, and pool after processing lun
				# processExPGConf($confFile);
			}
			elsif ($confFile =~ m/svpLdev/) { 
				
				next;  # will process ldev, pg, and pool after processing lun
				# processLdevConf($confFile);
			}
			elsif ($confFile =~ m/svpLunConf/) { 
			
				next; # process only afer HG
				#processLunConf($confFile);
			}
			elsif ($confFile =~ m/svpParityGroupConf/) { 
			
				next;
				# processPGConf($confFile);
			}
			elsif ($confFile =~ m/svpPoolConf/) { 
				
				next; # will process ldev, pg, and pool after processing lun
				# processPoolConf($confFile);
			}
			elsif ($confFile =~ m/svpPortConf/) { 
			
				processPortConf($confFile);
			}
			elsif ($confFile =~ m/svpResourceConf/) { 
			
				processResourceGroupConf($confFile);
			}
			# elsif ($confFile =~ m/svpPoolTierConf/) { 
			
				# processPoolTierConf($confFile);
			# }
			elsif ($confFile =~ m/svpWwnTARConf/) { 
			
				processWwnTarConf($confFile);
			}
		}
		
		# Creating a hash of dirFileList to easily lookup if file is present or not
		# specially for USPV
		my %params = map { $_ => 1 } @tmpDateDirFileList;
		
		# processing LU 
		foreach my $confFile (@tmpDateDirFileList) {
			if ($confFile =~ m/^\./) {   # to skip hidden files starting with "."
				next;
			}

			if($confFile =~ m/svpLunConf/) {	
				processLunConf($confFile);
			}
		}

		# Prepare owners
		&prepareOwners;

		# processing ldev 
		foreach my $confFile (@tmpDateDirFileList) {

			if ($confFile =~ m/^\./) {   # to skip hidden files starting with "."
				next;
			}
			
			# commenting the new Ldev format and using the old one to enable data processing of Ldev
			# without its resource grp id - old data
			if($confFile =~ m/svpLdev/) {	
			
				processLdevConf($confFile);
			}
		}
		
        # Create Owner resource.
        processOwnerconf();
        
		# processing PG data as we needed some aggregated data from ldev processing before processing PG
		if(exists($params{"svpParityGroupConf.txt"})) {    # added check for USPV as it doesnt has PG data (file)
				
			processPGConf("svpParityGroupConf.txt");
		}
		
		
		# processing ExPG data as we needed some aggregated data from ldev processing before processing ExPG
		if(exists($params{"svpExGroupConf.txt"})) {  # added check for USPV as it doesnt has ExPG data (file)
				
			processExPGConf("svpExGroupConf.txt");
		}
		
		# processing pool tier
		processPoolTierConf("svpPoolTierConf.txt");
		
		# processing pool 
		processPoolConf("svpPoolConf.txt");
		
		# processing/adding remaining storage attributes
		if(length($serialNumber) == 5) {
			
			if ($modelUspv eq 'true') {
				$modelName = "USP-V";
			}
			else {
				$modelName = "VSP";
			}
		}
		elsif(length($serialNumber) == 6 && $serialNumber =~ m/^2/) {
			
			$modelName = "HUS-VM";
		}
		elsif(length($serialNumber) == 6 && $serialNumber =~ m/^3/) {
			
			$modelName = "VSP G1000"; # Raid800
		}
		
		# count of pool volumes.. that are used to create pools + allc Ldev + unalloc ldev = phy capacity
		
		# allocated ldev phy capacity
		foreach my $ldev (keys %allocatedLdevMap) {
			$totalAllocCapacity += $allocatedLdevMap{$ldev};
		}
		
		# UnAllocated ldev phy capacity
		foreach my $ldev1 (keys %unAllocatedLdevMap) {
			$totalUnAllocCapacity += $unAllocatedLdevMap{$ldev1};
		}
		
		# poolVol ldev phy capacity
		my $poolVolPhyCapacity = 0;
		foreach my $ldev2 (keys %ldevPoolMap) {
			$poolVolPhyCapacity += $ldevPoolMap{$ldev2};
		}
		
		my $numberOfPoolVolumes =  keys(%ldevPoolMap);
		
		my $numberOfPhyLdevs = 0;
		foreach my $pg (keys %pgToLdevMapRef) {
			my $cnt = length @{$pgToLdevMapRef{$pg}->{"ldev"}};
			$numberOfPhyLdevs += $cnt;
		}
		
		my $numberOfVVOls = keys(%allocatedVVOlMap) + keys(%unAllocatedVVolMap);
		
		foreach my $pool (keys %poolToVVOLMapRef) {
			$totalVirtualCapacity += $poolToVVOLMapRef{"$pool"}->{"capacity"};
		}
		
		my $allocatedVVolCapacity = 0;
		foreach my $vvol (keys %allocatedVVOlMap) {
			$allocatedVVolCapacity += $allocatedVVOlMap{"$vvol"}
		}
		
		my $unAllocatedVVolCapacity = 0;
		foreach my $vvol1 (keys %unAllocatedVVolMap) {
			$unAllocatedVVolCapacity += $unAllocatedVVolMap{"$vvol1"}
		}
		
		# free physical capacity - commented this as calculating free sys cap from pg av cap
		# my $totalFreePhyCapacity = $totalPhySystemCapacity - ($totalAllocCapacity + $totalUnAllocCapacity + $poolVolPhyCapacity);  
		
		print $SnapshotFile "\n";
		print $SnapshotFile "R:raidStorage#$serialNumber\n";
		print $SnapshotFile "a:name=$serialNumber\n";
		print $SnapshotFile "a:svpIP=$svpIP\n";
		print $SnapshotFile "a:modelName=$modelName\n";
		print $SnapshotFile "a:svpMicroVersion=$microVer\n";
		print $SnapshotFile "a:cacheSizeMB=$storageCacheSize\n";
		print $SnapshotFile "a:noOfLdev=$noOfLdev\n";
		print $SnapshotFile "a:numberOfPhyLdevs=$numberOfPhyLdevs\n";
		
		# added check for modelUspv not true, because these variables are calculated through PG conf data 
		# which we do not get in case of USPV through raidcom 
		if ($modelUspv ne 'true') {
		
			print $SnapshotFile "a:noOfPg=$noOfPG\n";
			printf $SnapshotFile "a:totalPhyCapacity=%.2f\n",$totalPhySystemCapacity;  # sum of all pg cap
			printf $SnapshotFile "a:totalFreePhyCapacity=%.2f\n",$totalFreePhyCapacity;  # sum of all pg cap
		}
		
		printf $SnapshotFile "a:allocatedPhyCapacity=%.2f\n",$totalAllocCapacity;
		printf $SnapshotFile "a:unAllocatedPhyCapacity=%.2f\n",$totalUnAllocCapacity;
		printf $SnapshotFile "a:poolVolPhyCapacity=%.2f\n",$poolVolPhyCapacity;
		print $SnapshotFile "a:numberOfPools=$numberOfPools\n";
		print $SnapshotFile "a:numberOfPoolVols=$numberOfPoolVolumes\n";
		print $SnapshotFile "a:numberOfVvols=$numberOfVVOls\n";
		printf $SnapshotFile "a:totalVirtualCapacity=%.2f\n",$totalVirtualCapacity;
		printf $SnapshotFile "a:totalAllocatedVirtualCapacity=%.2f\n",$allocatedVVolCapacity;
		printf $SnapshotFile "a:totalUnAllocatedVirtualCapacity=%.2f\n",$unAllocatedVVolCapacity;
		print $SnapshotFile "\n";
		
	}
}

close (SNAPSHOT);

logMsg("conf processing completed. snapshot file created at $baseFolder/temp/svp/data/conf/Conf_$startTime"."_snapshot_$siteName"."_$svpIP"."_SVP.txt\n");

# zipping the snapshot file to Final File name provided
chdir ("$baseFolder/temp/svp/data/conf/");
my $confFilename = substr($snapshotFileName, rindex($snapshotFileName, '/')+1 );
my $retvalZip = system("zip $finalFileName $confFilename");

if ($retvalZip)
{
	logMsg("Error: Zipping snapshot file failed");
	print "zipping failed\n";
	exit 1;
}

logMsg("zipping outfile completed.");

# deleting snapshot file created at temp
unlink($snapshotFileName);

# adding serial number to volume
foreach my $poolName (keys %poolToVVOLMapRef) {

	foreach my $volName ( @{ $poolToVVOLMapRef->{$poolName}->{"vvol"} } ) {
		
		
	}
}

# create file to dump ldev to pool relation to aggregate data during perf processing 
# and also dump concatenatedPGMap for C-PGs -> Concatenated PG name - so perf processing may cerate combined resources
# only if lock file does not exist, write pool and C-PGs map to file
logMsg("waiting for conf lock.");
until (-e "$baseFolder/db/probe/raw/conf_$svpIP.lck"){
	
	logMsg("writing map for sharing.");
	open (ConfLock, ">$baseFolder/db/probe/raw/conf_$svpIP.lck");
	open (ConfShareFH, ">$baseFolder/db/probe/raw/confShare_$svpIP.pl");
	
	my $tempMap = { "poolToVVOLMapRef" => \%poolToVVOLMapRef,
			"concatenatedPGMap" => \%concatenatedPGMap,	
		};
	print ConfShareFH Dumper $tempMap;	
	
	close (ConfShareFH);
	close(ConfLock);
	last;
}

# deleting lock file
unlink("$baseFolder/db/probe/raw/conf_$svpIP.lck");

logMsg("Write completed. lock released");

logMsg("ends\n");

exit 0;


############## ENDS ##################



# sub to process HG configuration data
sub processHGConf {
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^PORT[ ]+GID[ ]+GROUP_NAME[ ]+Serial#[ ]+HMD[ ]+HMO_BITs/ ) {  
				
			next;
		}
		elsif ($currLine =~ m/^(CL[0-9A-Z]+[-A-Z]+)[ ]+([0-9]+)[ ]+(.*)[ ]+([0-9]+)[ ]+([A-Za-z\/_-]+)[ ]+(.*)$/ ) {
			
			my $portName = $1;
			my $hgID = $2;
			my $hgName = $3;
			my $serialNum = $4;
			my $hmd = $5;
			my $hmoBits = $6;

			# remove trailing space in hgName
			$hgName =~ s/\s+$//;
			
			# convert HG ID from decimal to hex and uppercase
			$hgID = uc ( sprintf("%x",$hgID) );
			
			print $SnapshotFile "R:raidHG#$serialNum-$portName-$hgID\n";
			print $SnapshotFile "a:name=$serialNum-$portName-$hgName\n";
			print $SnapshotFile "a:hgID=$hgID\n";
			print $SnapshotFile "a:hgName=$hgName\n";
			print $SnapshotFile "a:hostMode=$hmd\n";
			print $SnapshotFile "a:hostModeOption=$hmoBits\n";
			print $SnapshotFile "r:raidStorage#$serialNum,raidPort#$serialNum-$portName\n";
			print $SnapshotFile "\n";                  
		}
	}	
		
	close (CONF);
}


# sub to process ResourceGroup configuration data
sub processResourceGroupConf{
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line - RS_GROUP            RGID   V_Serial#  V_ID   V_IF    Serial#
		if ( $currLine =~ m/^RS_GROUP[ ]+RGID[ ]+V_Serial#[ ]+V_ID[ ]+V_IF[ ]+Serial#/ ) {  
				
			next;
		}
		else {
			my @arr = split (' ', $currLine);
						
			my $resGroupName = $arr[0];
			my $resGroupId = $arr[1];
			my $virtualSerialNum = $arr[2];
			my $serialNum = $arr[5];
			
			
			# TODO: add Virtual Serial number mapping
			
			print $SnapshotFile "R:raidResourceGroup#$serialNum-$resGroupId\n";
			print $SnapshotFile "a:name=$serialNum-$resGroupName\n";
			print $SnapshotFile "a:virtualSerialNumber=$virtualSerialNum\n";
			print $SnapshotFile "r:raidStorage#$serialNum\n";
			print $SnapshotFile "\n";                  
		}
	}	
		
	close (CONF);
}


# sub to process Port configuration data
sub processPortConf {
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^PORT[ ]+TYPE[ ]+ATTR[ ]+SPD[ ]+LPID[ ]+FAB[ ]+CONN[ ]+SSW[ ]+SL[ ]+Serial#[ ]+WWN[ ]+PHY_PORT/ ) {  
				
			next;
		}
		elsif ($currLine =~ m/^CL.*/ ) {
			
			my @arr = split (' ', $currLine);
			
			my $portName = $arr[0];
			my $type = $arr[1];
			my $attr = $arr[2];
			my $spd = $arr[3];
			my $lpid = $arr[4];
			my $fab = $arr[5];
			my $conn = $arr[6];
			my $ssw = $arr[7];
			my $SL = $arr[8];
			my $serialNum = $arr[9];
			my $wwn = $arr[10];
			my $phyPort = $arr[11];
			
			$serialNumber = $serialNum;  # some files may not have serial number field in their data, setting serialNum to a global variable to be used by those files
			
			print $SnapshotFile "R:raidPort#$serialNum-$portName\n";
			print $SnapshotFile "a:name=$serialNum-$portName\n";
			print $SnapshotFile "a:portType=$type\n";
			print $SnapshotFile "a:attribute=$attr\n";
			print $SnapshotFile "a:speed=$spd\n";
			print $SnapshotFile "a:loopId=$lpid\n";
			print $SnapshotFile "a:fabricMode=$fab\n";                  
			print $SnapshotFile "a:topology=$conn\n";                  
			print $SnapshotFile "a:lunSecurity=$ssw\n";                  
			print $SnapshotFile "a:slpr=$SL\n";                  
			print $SnapshotFile "a:wwn=$wwn\n";                  
			print $SnapshotFile "a:phyPort=$phyPort\n";     
			print $SnapshotFile "r:raidStorage#$serialNum\n";
			print $SnapshotFile "\n";                  
			     
		}
		
	}	
		
	close (CONF);
}



# sub to process Pool configuration data
sub processPoolConf {
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^PID[ ]+POLS[ ]+U\(%\)[ ]+SSCNT[ ]+Available\(MB\)[ ]+Capacity\(MB\)[ ]+Seq#[ ]+Num[ ]+LDEV#[ ]+H\(%\)/ ) {  
				
			next;
		}
		else {
			
			my @arr = split (' ', $currLine);
			
			my $poolId = $arr[0];
			my $pols = $arr[1];
			my $UPercent = $arr[2];
			my $SSCNT = $arr[3];
			my $availableCapacityGB = ( $arr[4]/1024 );
			my $totalCapacityGB = ( $arr[5]/1024 );
			my $serialNum = $arr[6];   		# seq# is serialNum
			my $numberOfPoolVolumes = $arr[7];	# number of pool volumes
			my $NumOfLdev = $arr[8];
			my $HPercent = $arr[9];
				
			$numberOfPools++;
			
			# removing leading zeros from PoolId name
			$poolId = sprintf("%d",$poolId);
			
			my $usedCapacity = $totalCapacityGB - $availableCapacityGB;
			
			my $currentVirtualCap = 0;
			if (exists $poolToVVOLMapRef{"$poolId"}) {
					
				$currentVirtualCap = $poolToVVOLMapRef{"$poolId"}->{"capacity"}; 
			}
			my $currentSubscriptionPercent = (($currentVirtualCap/$totalCapacityGB)*100) ;   # current vvol/phy capacity
						
			my $noOfVVols = @{ $poolToVVOLMapRef{"$poolId"}->{"vvol"} };
						
			print $SnapshotFile "R:raidPool#$serialNum-$poolId\n";
			print $SnapshotFile "a:name=$serialNum-$poolId\n";
			print $SnapshotFile "a:poolStatus=$pols\n";
			print $SnapshotFile "a:usageRate=$UPercent\n";
			print $SnapshotFile "a:noOfVolumes=$SSCNT\n";
			printf $SnapshotFile "a:availableCapacityGB=%.2f\n",$availableCapacityGB;
			printf $SnapshotFile "a:totalCapacityGB=%.2f\n",$totalCapacityGB;  
			print $SnapshotFile "a:noOfVVols=$noOfVVols\n";
			printf $SnapshotFile "a:usedCapacityGB=%.2f\n",$usedCapacity;
			printf $SnapshotFile "a:currentSubscriptionPercent=%.2f\n",$currentSubscriptionPercent;
			print $SnapshotFile "a:numberOfPoolVolumes=$numberOfPoolVolumes\n";                  
			print $SnapshotFile "a:thresholdRate=$HPercent\n";                  
			print $SnapshotFile "a:poolTierCount=$poolToTierCountMap{$poolId}\n";                  
			print $SnapshotFile "r:raidStorage#$serialNum\n";                  
			print $SnapshotFile "\n";                  
			     
		}
		
	}	
		
	close (CONF);
}


# sub for processing pool tier configuration info - only name and relations
sub processPoolTierConf {
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^PID[ ]+POLS[ ]+MODE[ ]+STS[ ]+DAT[ ]+TNO[ ]+TL_RANGE[ ]+TD_RANGE[ ]+.*/ ) {  
		
			next;
		}
		else {
			my @arr = split (' ', $currLine);
			
			my $poolId = $arr[0];
			my $tierNo = $arr[5];
		
			# removing leading zeros from PoolId name
			$poolId = sprintf("%d",$poolId);
			
			if ( $poolToTierCountMap{$poolId} == undef ) {
				$poolToTierCountMap{$poolId} = 1;
			}
			else {
				my $temp = $poolToTierCountMap{$poolId};
				$poolToTierCountMap{$poolId} = $temp + 1;
			}
						
			print $SnapshotFile "R:raidPoolTier#$serialNumber-$poolId-$tierNo\n";
			print $SnapshotFile "a:name=$serialNumber-$poolId-$tierNo\n";
			print $SnapshotFile "r:raidStorage#$serialNumber,raidPool#$serialNumber-$poolId\n";                  
			print $SnapshotFile "\n";                  
		}
	}
		
	close (CONF);
}


# sub to process WWN (svpWwnTARConf) configuration data
sub processWwnTarConf {
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^PORT[ ]+GID[ ]+GROUP_NAME[ ]+HWWN[ ]+Serial#[ ]+NICK_NAME/ ) {  
				
			next;
		}
		elsif ( $currLine =~ m/^(CL\w+[-A-Z]+)[ ]+([0-9]+)[ ]+(.*)[ ]+([a-zA-Z0-9]{16})[ ]+(\d+)[ ]+/ ) {
			
			my $portName = $1;
			my $hgId = $2;
			my $hgName = $3;
			my $wwnName = uc($4);  # wwn name is in lower case, converting to upper case
			my $serialNum = $5;
			
			push @{$hgIdPortWWNMap{$portName . "-" . $hgId}->{wwns}}, $wwnName;
			push @{$hgIdPortWWNMap{$portName . "-" . $hgId}->{hgs}}, $hgName;

			# convert HG ID from decimal to hex and uppercase
			$hgID = uc ( sprintf("%x",$hgID) );
			
			print $SnapshotFile "R:raidPortWWN#$serialNum-$portName-$wwnName\n";
			print $SnapshotFile "a:name=$serialNum-$portName-$wwnName\n";
			print $SnapshotFile "a:hgId=$hgId\n";
			print $SnapshotFile "a:hgName=$hgName\n";
			print $SnapshotFile "r:raidStorage#$serialNum,raidPort#$serialNum-$portName,raidHG#$serialNum-$portName-$hgId\n";                  
			print $SnapshotFile "\n";                  
		}
	}	
		
	close (CONF);
}


# sub to process Parity Group configuration data
sub processPGConf {
	
	my $configFile = shift;
	
	my %concatenatedPgData = ();
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^T[ ]+GROUP[ ]+Num_LDEV[ ]+U\(%\)[ ]+AV_CAP\(GB\)[ ]+R_LVL[ ]+R_TYPE[ ]+SL[ ]+CL[ ]+DRIVE_TYPE/ ) {  
				
			next;
		}
		else {
			
			my @arr = split (' ', $currLine);
			
			# if Raid type is in format (2D+2D)x2 -  that means it is a concatenated PG, hence merge the data to form a single resource
			# as 1-2[1-3] or 1-2[1-3 1-4 1-5] 
			if ($arr[6] =~ m/\([\dDP]+\+[\dDP]+\)x[0-9]/) {
				
				logMsg("CPG - TRUE:  $currLine\n");
				$concatenatedPgData{$arr[1]} = \@arr;
				
				# move to next line/PG and combine/merge such PGs later after complete iteration
				next;
			}
			
			my $TypeOfPG = $arr[0];
			my $parityGroup = $arr[1];
			my $NumOfLdev = $arr[2];
			my $UPercent = $arr[3];
			my $availableCapacityGB = $arr[4];
			my $RAIDLevel = $arr[5];
			my $RAIDType = $arr[6];   		# seq# is serialNum
			my $SL = $arr[7];
			my $CL = $arr[8];
			my $driveType = $arr[9];
			my $totalCapacity = $pgToLdevMapRef{$parityGroup}->{"capacity"} + $availableCapacityGB;  # sum of all ldev capacity of this PG + pg available cap
					
			$noOfPG++;	
			
			my $noOfUnAllocatedLdev = 0;
			@ldevListofPG = @{ $pgToLdevMapRef{"$parityGroup"}->{"ldev"} };
			foreach my $ldev (@ldevListofPG) {
					
				if(exists $unAllocatedLdevMap{$ldev}) {
					$noOfUnAllocatedLdev++;
				}
			}
						
			# commenting this part as the system capacity is now being calculated in Ldev processing			
			# $totalPhySystemCapacity += $totalCapacity;	
			$totalPhySystemCapacity += $availableCapacityGB; # adding free pg cap only, and used pg cap is added while processing Ldev  
			
			$totalFreePhyCapacity += $availableCapacityGB; # adding free cap of pg for totalSysFreeCap
						
			# making display names to have two digits. eg: 1-12 should be 01-12
			my @tmpArr = split('-', $parityGroup);
			print $SnapshotFile "R:raidPG#$serialNumber-$parityGroup\n";
			print $SnapshotFile "a:name=$serialNumber-$parityGroup\n";
			print $SnapshotFile "a:typeOfPG=$TypeOfPG\n";
			print $SnapshotFile "a:numberOfLdevs=$NumOfLdev\n";
			print $SnapshotFile "a:usageRate=$UPercent\n";
			printf $SnapshotFile "a:totalCapacityGB=%.2f\n",$totalCapacity;
			printf $SnapshotFile "a:availableCapacityGB=%.2f\n",$availableCapacityGB;
			print $SnapshotFile "a:unAllocatedVolume=$noOfUnAllocatedLdev\n";
			print $SnapshotFile "a:raidLevel=$RAIDLevel\n";                  
			print $SnapshotFile "a:raidType=$RAIDType\n";                  
			print $SnapshotFile "a:slpr=$SL\n";                  
			print $SnapshotFile "a:clpr=$CL\n";                  
			print $SnapshotFile "a:driveType=$driveType\n";                  
			print $SnapshotFile "r:raidStorage#$serialNumber\n";                  
			print $SnapshotFile "\n";                  
			     
		}
	}
	
	foreach my $cPG (keys %pgToLdevMapRef) {
		
		# regex for format a-b[c-d e-f] of C-PGs 
		if ($cPG =~ m/([\d]+-[\d]+)\[(.*)\]/) {
			my $headPG = $1;
			my @tempPgArr = split(' ', $2); # split the rest PGs by space, as C-PGs resources are created as 1-2[1-3 1-4 1-5]
			
			my @dataArr = @{ $concatenatedPgData{$headPG} };
			
			my $TypeOfPG = $dataArr[0];
			my $parityGroup = $cPG;
			my $NumOfLdev = $dataArr[2];
			my $availableCapacityGB = $dataArr[4];
			my $RAIDLevel = $dataArr[5];
			my $RAIDType = $dataArr[6];   		# seq# is serialNum
			my $SL = $dataArr[7];
			my $CL = $dataArr[8];
			my $driveType = $dataArr[9];
			my $totalCapacity = $pgToLdevMapRef{$cPG}->{"capacity"} + $availableCapacityGB;  # sum of cap of pg-ldevs + avCap of this PG +avCap of rest
			
			my $count = 1;
			
			foreach my $nonHeadPg (@tempPgArr) {
				
				@dataArr = @{ $concatenatedPgData{$nonHeadPg} };
				
				$NumOfLdev += $dataArr[2];
				$availableCapacityGB += $dataArr[4];
				$totalCapacity += $availableCapacityGB;
				$count++;
				
				# in some cases C-PGs have diff driveTypes, for such case setting it as blank
				# eg: (29-16 driveType: DKS5B-J300SS) & (30-16 driveType:DKR5C-J300SS)
				if ($driveType ne $dataArr[9]) {
					$driveType = "";
				}
				
			}
			
			# taking avg of Usage Rate for all concatenated PGs
			my $UPercent = ((($totalCapacity-$availableCapacityGB)/$totalCapacity)*100);
			
			$noOfPG++;	
			
			my $noOfUnAllocatedLdev = 0;
			@ldevListofPG = @{ $pgToLdevMapRef{"$parityGroup"}->{"ldev"} };
			foreach my $ldev (@ldevListofPG) {
					
				if(exists $unAllocatedLdevMap{$ldev}) {
					$noOfUnAllocatedLdev++;
				}
			}
			
			# commenting this part as the system capacity is now being calculated in Ldev processing			
			# $totalPhySystemCapacity += $totalCapacity;	
			$totalPhySystemCapacity += $availableCapacityGB; # adding free pg cap only, and used pg cap is added while processing Ldev  
			
			$totalFreePhyCapacity += $availableCapacityGB; # adding free cap of pg for totalSysFreeCap			
			
			print $SnapshotFile "R:raidPG#$serialNumber-$parityGroup\n";
			print $SnapshotFile "a:name=$serialNumber-$parityGroup\n";
			print $SnapshotFile "a:typeOfPG=$TypeOfPG\n";
			print $SnapshotFile "a:numberOfLdevs=$NumOfLdev\n";
			printf $SnapshotFile "a:usageRate=%.2f\n",$UPercent;
			printf $SnapshotFile "a:totalCapacityGB=%.2f\n",$totalCapacity;
			printf $SnapshotFile "a:availableCapacityGB=%.2f\n",$availableCapacityGB;
			print $SnapshotFile "a:unAllocatedVolume=$noOfUnAllocatedLdev\n";
			print $SnapshotFile "a:raidLevel=$RAIDLevel\n";                  
			print $SnapshotFile "a:raidType=$RAIDType\n";                  
			print $SnapshotFile "a:slpr=$SL\n";                  
			print $SnapshotFile "a:clpr=$CL\n";                  
			print $SnapshotFile "a:driveType=$driveType\n";                  
			print $SnapshotFile "r:raidStorage#$serialNumber\n";                  
			print $SnapshotFile "\n";                  
		
	}	
	}
		
	close (CONF);
}


# sub to process External Parity Groups configuration data
sub processExPGConf {
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^T[ ]+GROUP[ ]+Num_LDEV[ ]+U\(%\)[ ]+AV_CAP\(GB\)[ ]+R_LVL[ ]+E_TYPE[ ]+SL[ ]+CL[ ]+DRIVE_TYPE/ ) {  
				
			next;
		}
		else {
			
			my @arr = split (' ', $currLine);
			
			my $TypeOfExPG = $arr[0];
			my $parityGroup = $arr[1];
			my $NumOfLdev = $arr[2];
			my $UPercent = $arr[3];
			my $availableCapacityGB = $arr[4];
			my $RAIDLevel = $arr[5];
			my $EType = $arr[6];   		# seq# is serialNum
			my $SL = $arr[7];
			my $CL = $arr[8];
			my $driveType = $arr[9];
			# sum of all ldev capacity of this Ex PG + pg available cap
			my $totalCapacity = $exPgToLdevMap{"$serialNumber-E$parityGroup"}->{"capacity"} + $availableCapacityGB; 
		
			$noOfPG++;
			
			my $noOfUnAllocatedLdev = 0;
			@ldevListofPG = keys %{ $exPgToLdevMap{"$serialNumber-E$parityGroup"} };
			foreach my $ldev (@ldevListofPG) {
					
				if(exists $unAllocatedLdevMap{$ldev}) {
					$noOfUnAllocatedLdev++;
				}
			}
			
			# # TODO should we add total capacity of this ExPG to Total Phy system capacity ?
			# $totalPhySystemCapacity += $totalCapacity;	
			$totalPhySystemCapacity += $availableCapacityGB; # adding free pg cap only, and used pg cap is added while processing Ldev  
				
			$totalFreePhyCapacity += $availableCapacityGB; # adding free cap of pg for totalSysFreeCap
			
			print $SnapshotFile "R:raidPG#$serialNumber-E$parityGroup\n";   	# added 'E' before PG name for External PG
			print $SnapshotFile "a:name=$serialNumber-E$parityGroup\n";
			print $SnapshotFile "a:typeOfPG=$TypeOfExPG\n";
			print $SnapshotFile "a:numberOfLdevs=$NumOfLdev\n";
			print $SnapshotFile "a:usageRate=$UPercent\n";
			printf $SnapshotFile "a:totalCapacityGB=%.2f\n",$totalCapacity;
			printf $SnapshotFile "a:availableCapacityGB=%.2f\n",$availableCapacityGB;
			print $SnapshotFile "a:unAllocatedVolume=$noOfUnAllocatedLdev\n";
			print $SnapshotFile "a:raidLevel=$RAIDLevel\n";                  
			print $SnapshotFile "a:emulationType=$EType\n";                  
			print $SnapshotFile "a:slpr=$SL\n";                  
			print $SnapshotFile "a:clpr=$CL\n";                  
			print $SnapshotFile "a:driveType=$driveType\n";                  
			print $SnapshotFile "r:raidStorage#$serialNumber\n";                  
			print $SnapshotFile "\n";                  
			     
		}
		
	}	
		
	close (CONF);
}



# sub to process CLPR configuration data
sub processClprConf {
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^CLPR[ ]+CLPR_NAME[ ]+TC_CAP\(MB\)[ ]+TU_CAP\(MB\)[ ]+WP_CAP\(MB\)[ ]+SF_CAP\(MB\)[ ]+U\(%\)[ ]+W\(%\)[ ]+S\(%\)/ ) {  
				
			next;
		}
		else {
			
			my @arr = split (' ', $currLine);
			
			my $clprId = $arr[0];		# id is as 001, 003 ... change it to 1, 3 etc.
			my $clprName = $arr[1];
			my $TcCapMB = $arr[2];
			my $TUCapMB = $arr[3];
			my $WPCapMB = $arr[4];
			my $SFCapMB = $arr[5];
			my $UPercent = $arr[6];   		
			my $WPercent = $arr[7];
			my $SPercent = $arr[8];
			
			# removing leading zeros from clpr id
			$clprId = sprintf("%d",$clprId);
						
			print $SnapshotFile "R:raidClpr#$serialNumber-$clprId\n";
			print $SnapshotFile "a:name=$serialNumber-$clprId\n";
			print $SnapshotFile "a:clprName=$clprName\n";
			print $SnapshotFile "a:cacheMemoryCapacity=$TcCapMB\n";
			print $SnapshotFile "a:cacheMemoryUsedCapacity=$TUCapMB\n";
			print $SnapshotFile "a:writePendingDataCapacity=$WPCapMB\n";
			print $SnapshotFile "a:sidefileCapacity=$SFCapMB\n";
			print $SnapshotFile "a:usageRate=$UPercent\n";                  
			print $SnapshotFile "a:writePendingDataRate=$WPercent\n";                  
			print $SnapshotFile "a:sidefileUsageRate=$SPercent\n";                  
			print $SnapshotFile "r:raidStorage#$serialNumber\n";                  
			print $SnapshotFile "\n";                  
			     
		}
		
	}	
		
	close (CONF);
}



# sub to process Lun configuration data
sub processLunConf {
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^PORT[ ]+GID[ ]+HMD[ ]+LUN[ ]+NUM[ ]+LDEV[ ]+CM[ ]+Serial#[ ]+HMO_BITs/ ) {  
				
			next;
		}
		else {
			
			my @arr = split (' ', $currLine);
			
			my $portName = $arr[0];
			my $hgID = $arr[1];
			my $hmd = $arr[2];
			my $lunId = $arr[3];
			my $num = $arr[4];
			my $ldev = $arr[5];
			my $cm = $arr[6];   		# seq# is serialNum
			my $serialNum = $arr[7];
			my $hmoBits = $arr[8];
			
			# Find WWNs for this portName and hgId
			my @wwns = @{$hgIdPortWWNMap{$portName . "-" . $hgID}->{wwns}};
			if ($#wwns >= 0) {
				push @{$ldevWWNMap{$ldev}->{wwns}}, @wwns;
				# Get the Host group name list also
				my @hgnames = @{$hgIdPortWWNMap{$portName . "-" . $hgID}->{hgs}};
				if ($#hgnames >= 0) {
					push @{$ldevWWNMap{$ldev}->{hgs}}, @hgnames;
				}
			}
			# converting hgID to hex and uppercase
			$hgID = uc ( sprintf("%x",$hgID) );
			
			# converting lunId to hex and uppercase
			$lunId = uc ( sprintf("%x",$lunId) );
						
			# converting ldev num to hexadecimal : seperated ldev name
			my $ldevSignHex = ldevSignToHex($ldev);
			
			# making display names to have two digits. eg: 1-12 should be 01-12
			print $SnapshotFile "R:raidLU#$serialNum-$portName-$hgID-$lunId\n";
			print $SnapshotFile "a:name=$serialNum-$portName-$hgID-$lunId\n";
			print $SnapshotFile "a:hostMode=$hmd\n";
			print $SnapshotFile "a:portName=$portName\n";
			print $SnapshotFile "a:hgID=$hgID\n";
			print $SnapshotFile "a:lunId=$lunId\n";
			print $SnapshotFile "a:num=$num\n";                  
			print $SnapshotFile "a:ldev=$ldevSignHex\n";                  
			print $SnapshotFile "a:cm=$cm\n";                  
			print $SnapshotFile "a:hostModeOption=$hmoBits\n";                  
			print $SnapshotFile "r:raidStorage#$serialNum,raidPort#$serialNum-$portName,raidHG#$serialNum-$portName-$hgID,raidLdev#$serialNum-$ldevSignHex\n";                  
			print $SnapshotFile "\n";       
			
			# adding ldev name to %allocatedLdevMap
			$allocatedLdevMap{"$ldevSignHex"} = "";           
		}
		
	}	
		
	close (CONF);
}


# This method is used to create owner resources and its relation with MPB, port, pool, parity group. 
sub processOwnerconf {
 
	foreach my $wwnString (keys %ownerMap) {
    my $owner = $ownerMap{$wwnString}->{owner};
		if ($owner ne "") {
        
            print $SnapshotFile "R:raidOwner#$serialNumber-" . $ownerMap{$wwnString}->{owner} . "\n";
            print $SnapshotFile "a:name=$serialNumber-" . $ownerMap{$wwnString}->{owner} . "\n";
            
            # Get number of ldevs for this owner.
            my $noOfLdevs = @{$ownerMapping{$owner}->{ldevs}};
            
            print $SnapshotFile "a:noOfLdev=" . $noOfLdevs . "\n";
            
            print $SnapshotFile "r:raidStorage#$serialNumber";
            
            my @portNameList = @{$ownerMapping{$owner}->{ports}};
            my @pgNameList = @{$ownerMapping{$owner}->{pgs}};
            my @poolNameList = @{$ownerMapping{$owner}->{pools}};
            my @mpbNameList = @{$ownerMapping{$owner}->{mpbs}};

            foreach my $mpbName (keys %{{ map{$_=>1}@mpbNameList}}) {
                print $SnapshotFile ",raidMPB#$serialNumber-". $mpbName;
            }
           
            foreach my $portName (keys %{{ map{$_=>1}@portNameList}}) {
                print $SnapshotFile ",raidPort#$serialNumber-". $portName;
            }
            
            foreach my $pgName (keys %{{ map{$_=>1}@pgNameList}}) {
                print $SnapshotFile ",raidPG#$serialNumber-". $pgName;
            }
            
            foreach my $poolName (keys %{{ map{$_=>1}@poolNameList}}) {
                print $SnapshotFile ",raidPool#$serialNumber-". $poolName;
            }
            print $SnapshotFile "\n\n";
        }
        
	}
}

# sub to process Ldev configuration data
sub processLdevConf {
	
	my $configFile = shift;
	
	open (CONF, "<$topLevelFolder/$configFile");
	
	my $serialNum =  $ldev =  $SL =  $CL =  $volType =  $volCapacityGB =  $numLdev =  $Ldevs =  $numPort =  $Ports =  $FPoolId =  $volAttr  = "";
	my $RAIDLevel =  $RAIDType =  $numGroup =  $ParityGroups =  $driveType =  $driveCapacity =  $ldevNaming =  $sts =  $operateType =  $operatingRate = "";
	my $mpNum =  $ssid =  $EVendorId =  $EProductId =  $EVolId =  $EVolIdC =  $numEPort =  $EPorts =  $BPoolId =  $usedBlocks = "";
	my $tierRelocation =  $tierLevel =  $tierAllocLevel =  $volCapacityCyl = $qrdid = "";
	my @ParityGroupsArr = ();
	my @tierArr = ();
	
	my $resourceGroupId = $virtualLdevName = $virLdevSignHex = "";
	
	# fetching ResourceGroupID from Ldev Conf file name from Raidcom
	if ($configFile =~ m/svpLdev#([0-9]+)Conf/) {
		$resourceGroupId = $1;
	}
	
	while(my $currLine = readline(CONF)) {

		# header line
		if ( $currLine =~ m/^Serial#[ ]+:[ ]+([0-9]+)/ ) {  
				
			$serialNum = $1;
			next;
		}
		elsif ( $currLine =~ m/^LDEV[ ]+:[ ]+([0-9]+)/ ) { 
		
			$ldev = $1;
			
			if ( $currLine =~ m/^LDEV[ ]+:[ ]+([0-9]+)[ ]+VIR_LDEV[ ]+:[ ]+([0-9]+)/ ) { 
				
				$virtualLdevName = $2;
			}
			
			next;
		}
		elsif ( $currLine =~ m/^SL[ ]+:[ ]+([0-9]+)/ ) { 
		
			$SL = $1;
			next;
		}
		elsif ( $currLine =~ m/^CL[ ]+:[ ]+([0-9]+)/ ) { 
		
			$CL = $1;
			next;
		}
		elsif ( $currLine =~ m/^VOL_TYPE[ ]+:[ ]+(.*)/ ) { 
		
			$volType = $1;
			next;
		}
		elsif ( $currLine =~ m/^VOL_Capacity\(BLK\)[ ]+:[ ]+([0-9]+)/ ) { 
		
			$volCapacityGB = $1;
			$volCapacityGB = ( $volCapacityGB/(2048*1024) );  # in GB  blk * 2 = KB
			next;
		}
		elsif ( $currLine =~ m/^NUM_LDEV[ ]+:[ ]+([0-9]+)/ ) { 
		
			$numLdev = $1;
			next;
		}
		elsif ( $currLine =~ m/^LDEVs[ ]+:[ ]+([0-9]+)/ ) { 
		
			$Ldevs = $1;
			next;
		}
		elsif ( $currLine =~ m/^NUM_PORT[ ]+:[ ]+([0-9]+)/ ) { 
		
			$numPort = $1;
			next;
		}
		elsif ( $currLine =~ m/^PORTs[ ]+:[ ]+(.*)/ ) { 
		
			my $tmp = $1;
			my @tmpArr = split (':', $tmp);
			
			foreach $val (@tmpArr) {
				$Ports .= $val.",";
			}
			next;
		}
		elsif ( $currLine =~ m/^F_POOLID[ ]+:[ ]+(.*)/ ) { 
		
			$FPoolId = $1;
			next;
		}
		elsif ( $currLine =~ m/^VOL_ATTR[ ]+:[ ]+(.*)/ ) { 
		
			$volAttr = $1;
			next;
		}
		elsif ( $currLine =~ m/^RAID_LEVEL[ ]+:[ ]+(.*)/ ) { 
		
			$RAIDLevel = $1;
			next;
		}
		elsif ( $currLine =~ m/^RAID_TYPE[ ]+:[ ]+(.*)/ ) { 
		
			$RAIDType = $1;
			next;
		}
		elsif ( $currLine =~ m/^NUM_GROUP[ ]+:[ ]+([0-9]+)/ ) { 
		
			$numGroup = $1;
			next;
		}
		elsif ( $currLine =~ m/^RAID_GROUPs[ ]+:[ ]+(.*)/ ) { 
		
			my $tmp = $1;
			
			# adding code to identify and split ':' seperated PGs in case of Concatenated PGs
			# eg: RAID_GROUPs : 02-08 : 02-09
			my @tempArr = split(':',$tmp);
			
			foreach my $pg (@tempArr) {
				if ($pg ne '' ) {
					my @tArr = split ('-', $pg);
					push (@ParityGroupsArr,sprintf("%d",$tArr[0])."-".sprintf("%d",$tArr[1]));
			}
			}
			next;
		}
		elsif ( $currLine =~ m/^DRIVE_TYPE[ ]+:[ ]+(.*)/ ) { 
		
			$driveType = $1;
			next;
		}
		elsif ( $currLine =~ m/^DRIVE_Capa[ ]+:[ ]+([0-9]+)/ ) { 
		
			$driveCapacity = $1;
			$driveCapacity = ( $driveCapacity/(2048*1024) );  # in GB  blk * 2 = KB
			next;
		}
		elsif ( $currLine =~ m/^LDEV_NAMING[ ]+:[ ]+(.*)/ ) { 
		
			$ldevNaming = $1;
			next;
		}
		elsif ( $currLine =~ m/^STS[ ]+:[ ]+(.*)/ ) { 
		
			$sts = $1;
			next;
		}
		elsif ( $currLine =~ m/^OPE_TYPE[ ]+:[ ]+(.*)/ ) { 
		
			$operateType = $1;
			next;
		}
		elsif ( $currLine =~ m/^OPE_RATE[ ]+:[ ]+([0-9]+)/ ) { 
		
			$operatingRate = $1;
			next;
		}
		elsif ( $currLine =~ m/^MP#[ ]+:[ ]+([0-9]+)/ ) { 
		
			$mpNum = $1;
			
			# adding this hard-coded mapping for MPBnum to MPB name for VSP, HUS-VM, and VSP G1000
			$mpNum = getMpbMapping($serialNum, $mpNum);
			next;
		}
		elsif ( $currLine =~ m/^SSID[ ]+:[ ]+([0-9]+)/ ) { 
		
			$ssid = $1;
			next;
		}
		elsif ( $currLine =~ m/^E_VendorID[ ]+:[ ]+(.*)/ ) { 
		
			$EVendorId = $1;
			next;
		}
		elsif ( $currLine =~ m/^E_ProductID[ ]+:[ ]+(.*)/ ) { 
		
			$EProductId = $1;
			next;
		}
		elsif ( $currLine =~ m/^E_VOLID[ ]+:[ ]+(.*)/ ) { 
		
			$EVolId = $1;
			next;
		}
		elsif ( $currLine =~ m/^E_VOLID_C[ ]+:[ ]+([- A-Za-z_0-9]+)/ ) { 
		
			$EVolIdC = $1;
			next;
		}
		elsif ( $currLine =~ m/^NUM_E_PORT[ ]+:[ ]+([0-9]+)/ ) { 
		
			$numEPort = $1;
			next;
		}
		elsif ( $currLine =~ m/^E_PORTs[ ]+:[ ]+(.*)/ ) { 
		
			my $tmp = $1;
			my @tmpArr = split (':', $tmp);
			
			foreach $val (@tmpArr) {
				$EPorts .= $val.",";
			}
			next;
		}
		elsif ( $currLine =~ m/^B_POOLID[ ]+:[ ]+(.*)/ ) { 
		
			$BPoolId = $1;
			next;
		}
		elsif ( $currLine =~ m/^Used_Block\(BLK\)[ ]+:[ ]+([0-9]+)/ ) { 
		
			$usedGB = $1;
			$usedGB = ( $usedGB/(2048*1024) );  # in GB  blk * 2 = KB
			next;
		}
		elsif ( $currLine =~ m/^TIER_Relocation[ ]+:[ ]+(.*)/ ) { 
		
			$tierRelocation = $1;
			next;
		}
		elsif ( $currLine =~ m/^TIER_level[ ]+:[ ]+(.*)/ ) { 
		
			$tierLevel = $1;
			next;
		}
		elsif ( $currLine =~ m/^TIER#(\d)\(MB\)[ ]+:[ ]+[0-9]+/ ) {        
			my $tierNo = $1;
			push (@tierArr, $tierNo);
			next;
		}
		elsif ( $currLine =~ m/^TIER_Alloc_level[ ]+:[ ]+(.*)/ ) { 
		
			$tierAllocLevel = $1;
			next;
		}
		elsif ( $currLine =~ m/^VOL_Capacity\(cyl\)[ ]+:[ ]+([0-9]+)/ ) { 
		
			$volCapacityCyl = $1;
			next;
		}
		elsif ( $currLine =~ m/^QRDID[ ]+:[ ]+([0-9]+)/ ) { 
		
			$qrdid = $1;
			next;
		}
		elsif ( $currLine =~ m/^[\n ]+$/ ) { 
		
			# converting ldev num to hexadecimal : seperated ldev name
			my $ldevSignHex = ldevSignToHex($ldev);			
			
			# converting virtual ldev num to hexadecimal : seperated ldev name
			# ignoring 65534 as it's an Invalid VLDEV shown when ldev doesn't belong to any RG 
			if ( $virtualLdevName ne '' && $virtualLdevName ne '65534') {
				
				$virLdevSignHex = ldevSignToHex($virtualLdevName);
			}
				
			
			# creating concatenated PG names - space seperated eg: 1-2[1-3 1-4 1-5]
			my $pgArrSize = @ParityGroupsArr;
			
			if ($pgArrSize > 1) {
				
				# check if the same Concatenated PG is presented again with reversed names
				# if yes, don't re-create such PG name
				# eg: [RAID_GROUPs : 21-07 : 22-07]   and [RAID_GROUPs : 22-07 : 21-07]
				if ( !(exists $concatenatedPGMap{$ParityGroupsArr[0]} )) {
			
					$ParityGroups = $ParityGroupsArr[0]."[".$ParityGroupsArr[1];
					
					my $index = 2;
					for ($index..$pgArrSize-1) {
						$ParityGroups .= " ".$ParityGroupsArr[$index];
						$index++;
			}	
					
					$ParityGroups .= "]";
			
					# loop for creating concatenatedPGMap for sharing with perf 
					$index = 0;
					for ($index..$pgArrSize-1) {
						# adding entry of each PG in this map with its Head PG name
						$concatenatedPGMap{$ParityGroupsArr[$index]} = $ParityGroups;
						$index++;		
					}
			
					logMsg("Concatenated PGs: $ParityGroups");
				}
  				else {
  					$ParityGroups = $concatenatedPGMap{$ParityGroupsArr[0]};
  				}
			}
			else {
				$ParityGroups = $ParityGroupsArr[0];
			}
						
			# extracting port names from Ports or EPorts
			my %portList = ();
			
			if ($Ports ne '') {
				
				my @tmpArr = split (',',$Ports);
				
				foreach my $value (@tmpArr) {
					
					if ($value =~ m/(CL[A-Z0-9]+-[A-Z0-9]+)-.*/) {
						
						$portList{$1} = "";
					}
				}
			}
			elsif ($EPorts ne '') {
				
				my @tmpArr = split (',',$EPorts);
				
				foreach my $value (@tmpArr) {
					
					if ($value =~ m/(CL[A-Z0-9]+-[A-Z0-9]+)-.*/) {
						
						$portList{$1} = "";
					}
				}
			}
			######
			$noOfLdev++;
			
			print $SnapshotFile "\n";
			print $SnapshotFile "R:raidLdev#$serialNum-$ldevSignHex\n";
			print $SnapshotFile "a:name=$serialNum-$ldevSignHex\n";
			print $SnapshotFile "a:volumeType=$volType\n";                  
			printf $SnapshotFile "a:ldevCapacityGB=%.2f\n",$volCapacityGB;
			print $SnapshotFile "a:ports=$Ports\n";
			print $SnapshotFile "a:definedAlternatePaths=$EPorts\n";
			print $SnapshotFile "a:parentPoolId=$FPoolId\n";
			print $SnapshotFile "a:associatedPoolId=$BPoolId\n";
			print $SnapshotFile "a:parityGroup=$ParityGroups\n";
			print $SnapshotFile "a:volumeAttribute=$volAttr\n";
			print $SnapshotFile "a:externalVolId=$EVolIdC\n";
			print $SnapshotFile "a:ldevNaming=$ldevNaming\n";
			print $SnapshotFile "a:operatingRate=$operatingRate\n";
			print $SnapshotFile "a:raidLevel=$RAIDLevel\n";
			print $SnapshotFile "a:raidType=$RAIDType\n";
			print $SnapshotFile "a:driveModel=$driveType\n";
			printf $SnapshotFile "a:driveCapacity=%.2f\n",$driveCapacity;                  
			printf $SnapshotFile "a:usedCapacityGB=%.2f\n",$usedGB;
			print $SnapshotFile "a:mpb=$mpNum\n";                  
			print $SnapshotFile "a:ssid=$ssid\n"; 
			print $SnapshotFile "a:tierAllocLevel=$tierAllocLevel\n"; 
			print $SnapshotFile "a:tierLevel=$tierLevel\n"; 
			print $SnapshotFile "a:tierRelocation=$tierRelocation\n"; 
			print $SnapshotFile "r:raidStorage#$serialNum,raidMPB#$serialNum-$mpNum,";     # also add relation with ports from Ports or EPorts            
			my $owner = $ldevWWNMap{$ldev}->{owner};
			if ($owner ne "") {
				print $SnapshotFile "raidOwner#$serialNum-" . $ldevWWNMap{$ldev}->{owner} . ",";
               
               # store mapping from owner to MPB, ldev.
                push @{$ownerMapping{$owner}->{mpbs}}, $mpNum;
                push @{$ownerMapping{$owner}->{ldevs}}, $ldev;
			}
			
			if ($ParityGroups ne '' ) {
				
				# calculating totalSystemPhyCapacity by summing cap of all phy Ldev (Internal + External)
				$totalPhySystemCapacity += $volCapacityGB;	
				
				print $SnapshotFile "raidPG#$serialNum-$ParityGroups,";
				
				# adding ldev to pg - ldev list in this map pgToLdevMapRef and summing the ldev capacity to total PG Cap
				$noOfPhyLdev++;
				push ( @{ $pgToLdevMapRef{"$ParityGroups"}->{"ldev"} }, $ldevSignHex );
				$pgToLdevMapRef{"$ParityGroups"}->{"capacity"} += $volCapacityGB;     #{"1-2" => {ldev => [00:00:01,00:09:09],  capacity => 30}}
				
				if ($FPoolId eq 'NONE' || $FPoolId eq '') {  # F_PoolID = NONE or F_PoolID is blank
				
					if (exists $allocatedLdevMap{"$ldevSignHex"} ) {
						$allocatedLdevMap{"$ldevSignHex"} = $volCapacityGB;
					}
					else {
						$unAllocatedLdevMap{"$ldevSignHex"} = $volCapacityGB;
					}
				}
				else {
					# ldev DP  capacity/ pool capacity - # phy ldev used to create pool 
					$ldevPoolMap{"$ldevSignHex"} = $volCapacityGB;
					
					# adding relation to FPoolId i.e. the pool created from this ldev
					print $SnapshotFile "raidPool#$serialNum-$FPoolId,";
                    
                    # store owner to pool mapping
                    if ($owner ne '') {
                		push @{$ownerMapping{$owner}->{pools}}, $FPoolId;                
                    }
				}
                
                # store owner to pg mapping
                if ($owner ne '') {
                	push @{$ownerMapping{$owner}->{pgs}}, $ParityGroups;                
                }
			}
			elsif ($EVolIdC ne ''){
				
				# calculating totalSystemPhyCapacity by summing cap of all phy Ldev (Internal + External)
				$totalPhySystemCapacity += $volCapacityGB;	
								
				# External Phy Ldev - no info of PG/Ex-PG is present in its data
				$noOfPhyLdev++;
				
				if ($FPoolId eq 'NONE' || $FPoolId eq '') {  # F_PoolID = NONE or F_PoolID is blank
					
					if (exists $allocatedLdevMap{"$ldevSignHex"} ) {
						$allocatedLdevMap{"$ldevSignHex"} = $volCapacityGB;
						}
					else {
						$unAllocatedLdevMap{"$ldevSignHex"} = $volCapacityGB;
					}
				}
				else {
					# ldev DP  capacity/ pool capacity - # phy ldev used to create pool 
					$ldevPoolMap{"$ldevSignHex"} = $volCapacityGB;
					
					# adding relation to FPoolId i.e. the pool created from this ldev
					print $SnapshotFile "raidPool#$serialNum-$FPoolId,";

					# store owner to pool mapping
                    if ($owner ne '') {
                        push @{$ownerMapping{$owner}->{pools}}, $FPoolId;                
                    }
				}
			}
			elsif ($BPoolId ne 'UNKN' && $BPoolId ne '') {   # there is some B_PoolID which is a parent pool for this VVol
				
				if (exists $allocatedLdevMap{"$ldevSignHex"} ) {
					$allocatedVVOlMap{"$ldevSignHex"} = $volCapacityGB;
				}
				else {
					$unAllocatedVVolMap{"$ldevSignHex"} = $volCapacityGB;
				}
				
				$poolToVVOLMapRef{"$BPoolId"}; 
				push ( @{ $poolToVVOLMapRef{"$BPoolId"}->{"vvol"} }, "$serialNum-$ldevSignHex" );
				$poolToVVOLMapRef{"$BPoolId"}->{"capacity"} += $volCapacityGB;     #{"2" (poolId) => {ldev => [00:00:01,00:09:09],  capacity => 30}}
				
				# adding relation to BPoolId i.e. the VVOL created from this Pool 
				print $SnapshotFile "raidPool#$serialNum-$BPoolId,";
                
				# store owner to pool mapping
                if ($owner ne '') {
                    push @{$ownerMapping{$owner}->{pools}}, $BPoolId;            
                }
            }
			else{
				print "Volume Does not contain PG, F-Pool Id, or B-Pool Id:  $ldevSignHex\n";
				logMsg("Volume Does not contain PG, F-Pool Id, or B-Pool Id:  $ldevSignHex\n");
			}
			
			# code to check if volume is an External Volume i.e. if it belongs to exPgToLdevMap shared by perf
			for my $exPgName (keys %exPgToLdevMap) {
				
				if (exists $exPgToLdevMap{$exPgName}->{"$serialNum-$ldevSignHex"}) {  #if exists, Ldev is an External Ldev
					
					 $exPgToLdevMap{$exPgName}->{"capacity"} += $volCapacityGB;
					 # adding relation of ldev with External PG
					print $SnapshotFile "raidPG#$exPgName,";
				}
			}
			
			foreach my $portName (keys %portList) {
				print $SnapshotFile "raidPort#$serialNum-$portName,"; 
				
				# store owner to port mapping
				if ($owner ne '') {
                	push @{$ownerMapping{$owner}->{ports}}, $portName;                
				}
			}
			
			if ($resourceGroupId ne '') {
				print $SnapshotFile "raidResourceGroup#$serialNum-$resourceGroupId\n\n";
			}
			
			# adding Resource raidVLdev (virtual ldev or virtual name of a Ldev) and its relation with raidLdev
			if ( $virLdevSignHex ne '') {
				#@TODO Add Virtual Storage serial number and Virtual Storage (RG) name as attributes in VLdev
				print $SnapshotFile "R:raidVLdev#$serialNum-$resourceGroupId-$virLdevSignHex\n";
				print $SnapshotFile "a:name=$serialNum-$virLdevSignHex\n";
				print $SnapshotFile "r:raidStorage#$serialNum,raidLdev#$serialNum-$ldevSignHex,raidResourceGroup#$serialNum-$resourceGroupId\n";
			}
			
			# adding Resource raidLdevTier and its relation to Ldev
			foreach my $tierNo (@tierArr) {
				print $SnapshotFile "R:raidLdevTier#$serialNum-$ldevSignHex-$tierNo\n";
				print $SnapshotFile "a:name=$serialNum-$ldevSignHex-$tierNo\n";
				print $SnapshotFile "r:raidStorage#$serialNum,raidLdev#$serialNum-$ldevSignHex,\n";
				@tierArr = ();
			}
			
			print $SnapshotFile "\n\n";
			
			# re-setting all variables used for next ldev data
			$serialNum =  $ldev =  $SL =  $CL =  $volType =  $volCapacityGB =  $numLdev =  $Ldevs =  $numPort =  $Ports =  $FPoolId =  $volAttr  = "";
			$RAIDLevel =  $RAIDType =  $numGroup =  $ParityGroups =  $driveType =  $driveCapacity =  $ldevNaming =  $sts =  $operateType =  $operatingRate = "";
			$mpNum =  $ssid =  $EVendorId =  $EProductId =  $EVolId =  $EVolIdC =  $numEPort =  $EPorts =  $BPoolId =  $usedGB = "";
			$tierRelocation =  $tierLevel = $tierAllocLevel =  $volCapacityCyl = $qrdid = $virtualLdevName = $virLdevSignHex = "";          
			@ParityGroupsArr = ();      
		}
		
	}	
		
	close (CONF);
}




# subroutine to dump meta data. Input args: FILE_HANDLE
sub dumpMetaData {
	$fileHandle = shift;
	
	print $fileHandle "%meta\n";
	print $fileHandle "probe_id:".$siteName."_".$svpIP."\n";
	print $fileHandle "probe_type:SVP\n";
	print $fileHandle "probe_site:$siteName\n";
	print $fileHandle "probe_server:$svpIP\n";
	print $fileHandle "probe_version:1.0\n";
	print $fileHandle "%meta\n\n";
	
}

# This function is used to log a message in the log file. It logs the message in the following format:
# [YYYY-MM-DD HH:MM:ss,SSS]  [SVP-<IP Address>] [Perf_Collection] <Log message>
#
# @param :
# $_[0] - Log message.
#
# @return :
#   Nothing
sub logMsg
{
    # This variable is used to store the complete path of probe specific folder in db/probe folder.
    my $svpLogFolder = "";

    # Set log folder path.
    $svpLogFolder = $baseFolder."/logs/SVPProbe";

    # If log folder does not exist then create it.
    if (!(-e $svpLogFolder))
    {
        # TODO: Check the return value of mkpath.
        mkpath($svpLogFolder);
    }

    # Get the current date and time.
    my ($seconds, $microseconds) = gettimeofday;
    my $currentTime = strftime("%Y-%m-%d %H:%M:%S", localtime($seconds));

    # Get the date from the given date and time .
    my($date, $time) = split(' ', $currentTime, 2);

    # Set the name of log file.
    $logFile = $svpLogFolder."/SVPProbe.".$date.".log";

    # Open the log file.
    open(LOG_HANDLE, ">>", $logFile);# or die logMsg("Error: Not able to open the file: [$logFile]");

    # Read input parameters.
    my $logMsg = $_[0];

    # For getting time in a given format.
    $currentTime = "[".$currentTime.",".$microseconds."]";

    # Construct the final log message.
    my $finalMsg = $currentTime." [SVP-".$svpIP."] [Conf_Collection] ".$logMsg."\n";

    # Dump the final log message in log file.
    print LOG_HANDLE $finalMsg;

   close (LOG_HANDLE);
}

# subroutine to trim/remove leading and trailing spaces from a string
sub trim {
	my $string = shift;
	$string =~ s/^\s+//;
	$string =~ s/\s+$//;
	return $string;
}

# sub to convert Ldev number from decimal to ':' separated Hex
sub ldevSignToHex {

	my $ldev = shift;
	
	my $ldevSignHex = uc (sprintf("%x",$ldev));
	my @tempLdevArr = (0,0,0,0);
	for my $index (0..length($ldevSignHex)-1) {
			
		my $num = substr($ldevSignHex,$index,1);
		push (@tempLdevArr, $num);
	}
	my $size = @tempLdevArr;
	my $from = $size - 4 ;
	my $ldevName = "";
	my $cntr = 0;
	for my $in ($from..$size-1) {
		
		$ldevName .= $tempLdevArr[$in];
		$cntr++;
		if($cntr == 2) {
			$ldevName .= ":";	
		}
	}	
					
	$ldevSignHex = "00:$ldevName";
	
	return $ldevSignHex;			
}


# method to provide MPB id -> MPB name mapping for VSP, HUS-VM, and VSP G1000
sub getMpbMapping {

	my $serialNum = shift;
	my $mpbNum = shift;
	
	# case for VSP 
	if( length($serialNum) == 5 && $modelUspv ne 'true') {
		if ($mpbNum == 0) {
			$mpbNum = "MPB-1MA";
		}
		elsif ($mpbNum == 1) {
			$mpbNum = "MPB-1MB";
		}
		elsif ($mpbNum == 2) {
			$mpbNum = "MPB-2MC";
		}
		elsif ($mpbNum == 3) {
			$mpbNum = "MPB-2MD";
		}
		elsif ($mpbNum == 4) {
			$mpbNum = "MPB-1ME";
		}
		elsif ($mpbNum == 5) {
			$mpbNum = "MPB-1MF";
		}
		elsif ($mpbNum == 6) {
			$mpbNum = "MPB-2MG";
		}
		elsif ($mpbNum == 7) {
			$mpbNum = "MPB-2MH";
		}
		
		return $mpbNum;
	}
	elsif ( length($serialNum) == 6 && $serialNum =~ m/^2[0-9]+/) {  # case for HUS-VM	
		if ($mpbNum == 0) {
			$mpbNum = "MPU-10";
		}
		elsif ($mpbNum == 1) {
			$mpbNum = "MPU-11";
		}
		elsif ($mpbNum == 2) {
			$mpbNum = "MPU-20";
		}
		elsif ($mpbNum == 3) {
			$mpbNum = "MPU-21";
		}
		
		return $mpbNum;
	}
	elsif ( length($serialNum) == 6 && $serialNum =~ m/^3[0-9]+/) {  # case for VSP G1000
		if ($mpbNum == 0) {
			$mpbNum = "MPB-1MA";
		}
		elsif ($mpbNum == 1) {
			$mpbNum = "MPB-1MB";
		}
		elsif ($mpbNum == 2) {
			$mpbNum = "MPB-1PE";
		}
		elsif ($mpbNum == 3) {
			$mpbNum = "MPB-1PF";
		}
		elsif ($mpbNum == 4) {
			$mpbNum = "MPB-2MA";
		}
		elsif ($mpbNum == 5) {
			$mpbNum = "MPB-2MB";
		}
		elsif ($mpbNum == 6) {
			$mpbNum = "MPB-2PE";
		}
		elsif ($mpbNum == 7) {
			$mpbNum = "MPB-2PF";
		}
		elsif ($mpbNum == 8) {
			$mpbNum = "MPB-1MC";
		}
		elsif ($mpbNum == 9) {
			$mpbNum = "MPB-1MD";
		}
		elsif ($mpbNum == 10) {
			$mpbNum = "MPB-1PL";
		}
		elsif ($mpbNum == 11) {
			$mpbNum = "MPB-1PM";
		}
		elsif ($mpbNum == 12) {
			$mpbNum = "MPB-2MC";
		}
		elsif ($mpbNum == 13) {
			$mpbNum = "MPB-2MD";
		}
		elsif ($mpbNum == 14) {
			$mpbNum = "MPB-2PL";
		}
		elsif ($mpbNum == 15) {
			$mpbNum = "MPB-2PM";
		}
		
		return $mpbNum;	
	}
	else {
		return $mpbNum;
	}
}

sub prepareOwners {
	push @{$ldevWWNMap{$ldev}->{wwns}}, @wwns;
	foreach my $ldev (keys(%ldevWWNMap)) {
		my $wwnString = convertListToUniqueString(@{$ldevWWNMap{$ldev}->{wwns}});
		my $owner = $ownerMap{$wwnString}->{owner};
		if ($owner eq "") {
			$owner = convertListToUniqueString(@{$ldevWWNMap{$ldev}->{hgs}});
			$ldevWWNMap{$ldev}->{owner} = $owner;
			$ownerMap{$wwnString}->{owner} = $owner;
		}
		else {
			$ldevWWNMap{$ldev}->{owner} = $owner;
		}
	}

}

sub convertListToUniqueString {
	my (@list) = @_;
	my ($string) = "";

	my (%alreadyProcessed) = ();

	foreach my $member (sort{ "\L$a" cmp "\L$b" } (@list)) {
		$member =~ s/\s+$//g;
		next if ($alreadyProcessed{lc($member)} == 1);
		$alreadyProcessed{lc($member)} = 1;
		my $match = findLongestSubstringMatch($member, $string);
		if ($match == 0) {
			if ($string eq "") {
				$string = $member;
			}
			else {
				$string .= "-" . $member;
			}
		}
		elsif ($match > 3) { # There has to be reasonable match
			$string .= "_" . substr($member, $match);
		}
		else {
			$string .= "-" . $member;
		}
	}
	if (length($string) > 50) { # String to long then try truncating it
		return substr($string, 0, index($string, "_"));
	}
	return $string;
}

sub findLongestSubstringMatch {
	my ($needle, $haystack) = @_;
	my @matches;

	$needle = lc ($needle);
	$haystack = lc ($haystack);

    for my $start (0..0) {
        for my $len ($start+1 .. length $needle) {
            my $substr = substr($needle, $start, $len);
            push @matches, $haystack =~ m[($substr)]g;
        }
    }

    my ($len, $longest) = 0;
    length > $len and ($longest, $len) = ($_, length) for @matches;
	
	return $len;
}
