# Copyright 2008-2014 Cumulus Systems Incorporated.
# All Rights Reserved.

# This file contains the code to process the raw Configuration data for the IBM XIV Storage and dump it in final MARS format.
#
# @param : Input Zip File Name  - Name of the Zip file containing raw conf data.
# @param : Site Name            - MARS Site Name.
# @param : XIV IP Address       - XIV Storage IP Address
# @param : Start Time           - Start Time.
# @param : Output Zip File Name - Name of the final MARS format conf zip file.
#
# @return : In case of Success, returns 0. In case of Failure, returns 1.
#
# Sample command: perl ibmxivRawConfDataProcessor.pl <input zip file name> siteName=<siteName> probeServer=<XIV IP Address> startTime=<start time> <output zip file name>

#!/usr/bin/perl -w

# It is used for strict compilation.
use strict;

# It is used to get base file name from the complete file name.
use File::Basename;

# This is used to create folder recursively.
use File::Path qw(mkpath);

# This is use to move folder.
use File::Copy;

# It is used to indicate the path where common module is placed.
use lib "/usr/local/megha/lib/common/perl";

# It is required for logging information.
use commonLogModule;

# It is used for getting Configuration data.
use commonDataParsingUtil;

# It is used for getting probe Configuration metadata.
use commonProbeConfUtil;

# It is required for executing commands.
use commonPerlUtil;

# ----------------------------------------------------------------------------------------------------------------------------------------------------
# GLOBAL Variables
# ----------------------------------------------------------------------------------------------------------------------------------------------------
# This variable is used to store the base folder path on the MARS probe.
my $baseFolder = "/usr/local/megha";

# This variable is used to store the name of Raw configuration data file.
my $rawConfFile = "";

# This variable is used to store the return status of function calls.
my $status = 0;

# This variable is used to store the XIV Storage IP Address.
my $xivIpAddress = "";

# This variable is used to store the Configuration data start time.
my $startTime = "";

# This variable is used to store the name of the final file in MARS format.
my $finalConfFileName = "";

# This variable is used to store the MARS Site name.
my $marsSiteName = "";

# This variable holds the complete name of MARS format snapshot file.
my $tempConfFilePath = "";

# This variable holds the location where extracted files should be kept.
my $tmpDataDir = "";

# This variable is used to store the file handle of MARS configuration file.
my $CONF_HANDLE;

# This variable stores Storage Name.
my $storageName = "";

# This variable keeps track of the line containing column header whose data we need to extract.
my $isHeaderInfo = 0;

# This variable keeps track of line of which we need to do column related parsing.
my $isDataStart = 0;

# This variable stores the probe type.
my $probeType = "IbmXiv";

# This variable stores commonLogModule instance.
my $logObj = "";

# This variable stores commonDataParsingUtil instance.
my $dataParsingObj = "";
# ----------------------------------------------------------------------------------------------------------------------------------------------------
# Main function
# ----------------------------------------------------------------------------------------------------------------------------------------------------
# Initialize the environment.
$status = init();
if (0 != $status)
{
    $logObj->error("Call to init() failed.");
    goto EXIT;
}

# Process raw conf data and dump it in final MARS format.
$status = dumpProcessedData();
if (0 != $status)
{
    $logObj->error("Call to dumpProcessedData() failed.");
    goto EXIT;
}

# De-init the environment.
deInit();

EXIT:

exit $status;

# ----------------------------------------------------------------------------------------------------------------------------------------------------
# Sub-routines
# ----------------------------------------------------------------------------------------------------------------------------------------------------

# This function is used to initialize the environment to run the Perl script correctly.
#
# @affected global variables :
#   $marsSiteName
#   $xivIpAddress
#   $startTime
#   $finalConfFileName
#   $tempConfFilePath
#   $tmpDataDir
#
# @return :
#   0 if Success
#   1 if Error
sub init
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable stores Log folder path.
    my $logFolder = $baseFolder."/logs";

    # If log folder does not exist then create it.
    if (! (-e $logFolder))
    {
        mkpath($logFolder);
    }

    # Get commonLogModule instance.
    $logObj = commonLogModule->getInstance($logFolder, $probeType, $xivIpAddress);

    # If number of command line arguments are not correct then quit.
    if (5 != ($#ARGV + 1))
    {
        $logObj->error("Number of arguments to ibmxivRawConfDataProcessor.pl are not correct. Total input arguments = ".($#ARGV + 1));
        $retVal = 1;

        goto EXIT;
    }

    # Get the absolute path of zip file name to be processed from command line argument.
    my $confZipFile = $ARGV[0];

    # Get siteName from command line argument. Site Name will be in the format "siteName=<SiteName>".
    $marsSiteName = $ARGV[1];
    $marsSiteName = substr($marsSiteName, index($marsSiteName, '=') + 1);

    # Get XIV IP address from command line argument. It will be in the format: "probeServer=<XIV IP Address>".
    $xivIpAddress = $ARGV[2];
    $xivIpAddress = substr($xivIpAddress, index($xivIpAddress, '=') + 1);

    # Update the final log message information with populated XIV probe id.
    $logObj->setProbeId($xivIpAddress);

    # Get configuration start time from command line argument. Start time will be in the format: "startTime=<start time>".
    $startTime = $ARGV[3];
    $startTime = substr($startTime, index($startTime, '=') + 1);

    # Get output file name to which processed configuration data will be stored.
    $finalConfFileName = $ARGV[4];

    # Get commonDataParsingUtil instance.
    $dataParsingObj = commonDataParsingUtil->getInstance($baseFolder, $probeType, $xivIpAddress, $logObj);

    # This variable is used to store the path of Probe folder in db/probe.
    my $xivProbeFolder = $baseFolder."/db/probe/".$marsSiteName."/IbmXiv_".$xivIpAddress;
    $logObj->info("Creating folder: [$xivProbeFolder].");

    # Create the folder for this XIV Probe in the probe folder.
    unless (defined eval {mkpath($xivProbeFolder)})
    {
        $logObj->error("Not able to create folder: [$xivProbeFolder].");
        $retVal = 1;

        goto EXIT;
    }

    # This variable hold temporary conf data directory path.
    $tmpDataDir = $xivProbeFolder."/temp/conf";

    # Create the folder for temporary conf data.
    $logObj->info("Creating temp Conf data path: [$tmpDataDir].");

    unless (defined eval {mkpath($tmpDataDir)})
    {
        $logObj->error("Not able to create folder: [$tmpDataDir].");
        $retVal = 1;

        goto EXIT;
    }

    # Extracting zip file to temp directory.
    $retVal = system( "unzip -o $confZipFile -d $tmpDataDir" );
    if (0 != $retVal)
    {
        # TODO: Add source and destination file/folder in log message.
        $logObj->error("UnZipping raw conf file failed");
        $retVal = 1;

        goto EXIT;
    }

    # Set the final Configuration file name.
    my $tempConfFileName = $marsSiteName."_".$xivIpAddress."_snapshot_".$startTime.".txt";
    $logObj->info("IBM XIV Conf File name: [$tempConfFileName].");

    # Set the final Configuration file path.
    $tempConfFilePath = $tmpDataDir."/".$tempConfFileName;
    $logObj->info("IBM XIV Conf File path: [$tempConfFilePath].");

    # Open the final MARS configuration file.
    open($CONF_HANDLE, ">", $tempConfFilePath) or die $logObj->error("Not able to open the file: [$tempConfFilePath].");

EXIT:

    return $retVal;
}

# This function is used to process XIV Storage raw conf data and dump it in final MARS format.
#
# @affected global variables :
#   None
#
# @return :
#   0 if Success
#   1 if Error
sub dumpProcessedData
{
    # This variable is used to store the return value of function calls.
    my $retVal = 0;

    # This variable stores IBM XIV Storage configuration metadata.
    my $metaData = "";

    # Get commonPerlUtil instance.
    my $probeConfUtilObj = commonProbeConfUtil->getInstance($baseFolder, $probeType, $xivIpAddress, $logObj);

    # This function dumps the probe metadata in final mars configuration file.
    $probeConfUtilObj->getFormattedProbeConfMetadata($marsSiteName, $startTime, 10, $metaData);

    # Dump the Metadata for the IBM XIV probe in the configuration file.
    print $CONF_HANDLE $metaData;

    # This function dumps the processed Storage resource conf data in final mars format.
    processStorageConfData();

    # This function dumps the processed Host resource conf data in final mars format.
    processHostConfData();

    # This function dumps the processed Volume resource conf data in final mars format.
    processVolumeConfData();

    # This function dumps the processed Pool resource conf data in final mars format.
    processPoolConfData();

    # This function dumps the processed Disk resource conf data in final mars format.
    processDiskConfData();

    # This function dumps the processed Local FC Port resource conf data in final mars format.
    processLocalFcPortConfData();

    # This function dumps the processed Host FC Port resource conf data in final mars format.
    processHostFcPortConfData();

    # This function dumps the processed LUN resource conf data in final mars format.
    processLunConfData();

    # This variable is used to store the command to Zip the final Mars Conf file.
    my $cmd = "zip -q -j '$finalConfFileName' '$tempConfFilePath'" ;
    $logObj->info("Running command: zip -q -j '$finalConfFileName' '$tempConfFilePath'");

    # Get commonPerlUtil instance.
    my $perlUtilObj = commonPerlUtil->getInstance($baseFolder, $probeType, $xivIpAddress, $logObj);

    # Run the command to Zip the final Mars Conf file.
    my $exitCode = $perlUtilObj->executeSystemCmd($cmd);
    if (0 != $exitCode)
    {
        # If there is some problem is creating zip file then it is an error.
        $logObj->error("Failed to Zip the final Mars Conf file.");
        $retVal = 1;

        goto EXIT;
    }

    # Deleting snapshot file created at temp directory.
    unlink($tempConfFilePath);

EXIT:

    return $retVal;
}

# This function is used to process Storage resource raw conf data and dump it in final MARS format.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   1 if Error
sub processStorageConfData
{
    # This variable stores System ID.
    my $id = "";

    # This variable stores System Type.
    my $type = "";

    # This variable stores System Model.
    my $model = "";

    # This variable stores System Serial Number.
    my $serialNumber = "";

    # This variable stores System Consumed capacity.
    my $consumedCapacity = "";

    # This variable holds Storage version.
    my $version = "";

    # This variable keeps track of line containing version information.
    my $isVersionInfo = 0;

    # This array is used to store the required column numbers of a resource.
    my @columnNumberList = (0, 1, 2, 3, 4, 5, 6, 7, 8);

    # This array is used to store the column value of each column of a resource.
    my @columnValueList = ();

    # This hash is used to store the name of the resource and the column header name corresponding to each record.
    my %columnHeaderPositionHash = ();

    $rawConfFile = $tmpDataDir."/$startTime/xivStorageConf.dump";

    $logObj->info("Reading raw configuration data for Storage resource.");

    open(CONF_DUMP, $rawConfFile) or die $logObj->error("Not able to open the file: [$rawConfFile].");

    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        # Get System Name.
        if (/^(\s*)system_name(\s*)(.+)(\s*)$/)
        {
            $storageName = $3;

            # Remove trailing spaces.
            $storageName =~ s/\s+$//;

            # Replace space by underscore in storage name.
            $storageName =~ s/ /_/g;

            # Replace "^" by underscore in storage name.
            $storageName =~ s/\^/_/g;
        }
        # Get System ID.
        elsif (/^(\s*)system_id(\s*)(.+)(\s*)$/)
        {
            $id = $3;

            # Remove trailing spaces.
            $id =~ s/\s+$//;
        }
        # Get System Type.
        elsif (/^(\s*)machine_type(\s*)(.+)(\s*)$/)
        {
            $type = $3;

            # Remove trailing spaces.
            $type =~ s/\s+$//;
        }
        # Get System Model.
        elsif (/^(\s*)machine_model(\s*)(.+)(\s*)$/)
        {
            $model = $3;

            # Remove trailing spaces.
            $model =~ s/\s+$//;
        }
        # Get System SerialNumber.
        elsif (/^(\s*)machine_serial_number(\s*)(.+)(\s*)$/)
        {
            $serialNumber = $3;

            # Remove trailing spaces.
            $serialNumber =~ s/\s+$//;
        }
        # Get System Consumed capacity.
        elsif (/^(\s*)consumed_capacity(\s*)(.+)(\s*)$/)
        {
            $consumedCapacity = $3;

            # Remove trailing spaces.
            $consumedCapacity =~ s/\s+$//;
        }
        elsif (/^(\s*)Version(\s*)(.+)(\s*)$/)
        {
            $isVersionInfo = 1;
        }
        # Get version info.
        elsif (1 == $isVersionInfo)
        {
            $version = $_;

            # Remove trailing spaces.
            $version =~ s/\s+$//;

            $isVersionInfo = 0;
        }
        elsif (/^(\s*)(.+)>>system_capacity_list(\s*)$/)
        {
            $isHeaderInfo = 1;
        }
        # Get different capacity information about storage.
        elsif (1 == $isHeaderInfo)
        {
            $dataParsingObj->getColumnDataPosition($_, \%columnHeaderPositionHash);

            $isHeaderInfo = 0;
            $isDataStart = 1;
        }
        elsif (1 == $isDataStart)
        {
            print $CONF_HANDLE "R:ixStorage#$storageName\n";
            print $CONF_HANDLE "a:name=$storageName\n";
            print $CONF_HANDLE "a:id=$id\n";
            print $CONF_HANDLE "a:type=$type\n";
            print $CONF_HANDLE "a:version=$version\n";
            print $CONF_HANDLE "a:model=$model\n";
            print $CONF_HANDLE "a:serialNumber=$serialNumber\n";
            print $CONF_HANDLE "a:consumedCapacity=$consumedCapacity\n";

            $dataParsingObj->getColumnDataValues($_, \%columnHeaderPositionHash, \@columnNumberList, \@columnValueList);

            my $softCapacity = convertTBCapToGB(@columnValueList[0]);
            my $hardCapacity = convertTBCapToGB(@columnValueList[1]);
            my $maxPoolSize = convertTBCapToGB(@columnValueList[2]);
            my $freeHardCapacity = convertTBCapToGB(@columnValueList[3]);
            my $freeSoftCapacity = convertTBCapToGB(@columnValueList[4]);

            print $CONF_HANDLE "a:softCapacity=$softCapacity\n";
            print $CONF_HANDLE "a:hardCapacity=$hardCapacity\n";
            print $CONF_HANDLE "a:maxPoolSize=$maxPoolSize\n";
            print $CONF_HANDLE "a:freeHardCapacity=$freeHardCapacity\n";
            print $CONF_HANDLE "a:freeSoftCapacity=$freeSoftCapacity\n";
            print $CONF_HANDLE "a:spareModules=@columnValueList[5]\n";
            print $CONF_HANDLE "a:spareDisks=@columnValueList[6]\n";
            print $CONF_HANDLE "a:targetSpareModules=@columnValueList[7]\n";
            print $CONF_HANDLE "a:targetSpareDisks=@columnValueList[8]\n";

            $isDataStart = 0;
        }
        else
        {
            # Current line is of no use so ignore it.
        }
    }

    close (CONF_DUMP);
}

# This function is used to process Host resource raw conf data and dump it in final MARS format.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   1 if Error
sub processHostConfData
{
    # This array is used to store the required column numbers of a resource.
    my @columnNumberList = (0, 1, 2);

    # This array is used to store the column value of each column of a resource.
    my @columnValueList = ();

    # This hash is used to store the name of the resource and the column header name corresponding to each record.
    my %columnHeaderPositionHash = ();

    # This variable stores host name.
    my $hostName = "";

    $rawConfFile = $tmpDataDir."/$startTime/xivHostConf.dump";

    $logObj->info("Reading raw configuration data for Host resource.");

    open(CONF_DUMP, $rawConfFile) or die $logObj->error("Not able to open the file: [$rawConfFile].");

    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        if (/^(\s*)(.+)>>host_list(\s*)$/)
        {
            $isHeaderInfo = 1;
        }
        elsif (/^(\s*)(.+)>>(\s*)$/)
        {
            $isDataStart = 0;
        }
        elsif (1 == $isHeaderInfo)
        {
            $dataParsingObj->getColumnDataPosition($_, \%columnHeaderPositionHash);

            $isHeaderInfo = 0;
            $isDataStart = 1;
        }
        elsif (1 == $isDataStart)
        {
            $dataParsingObj->getColumnDataValues($_, \%columnHeaderPositionHash, \@columnNumberList, \@columnValueList);

            $hostName = @columnValueList[0];

            # Replace space by underscore in host name.
            $hostName =~ s/ /_/g;

            print $CONF_HANDLE "R:ixHost#$storageName^$hostName\n";
            print $CONF_HANDLE "a:name=$storageName^$hostName\n";
            print $CONF_HANDLE "a:type=@columnValueList[1]\n";
            print $CONF_HANDLE "a:fcPorts=@columnValueList[2]\n";
            print $CONF_HANDLE "r:ixStorage#$storageName\n";
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    close (CONF_DUMP);
}

# This function is used to process Volume resource raw conf data and dump it in final MARS format.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   1 if Error
sub processVolumeConfData
{
    $rawConfFile = $tmpDataDir."/$startTime/xivVolumeConf.dump";

    # This array is used to store the required column numbers of a resource.
    my @columnNumberList = (0, 1, 4, 6);

    # This array is used to store the column value of each column of a resource.
    my @columnValueList = ();

    # This hash is used to store the name of the resource and the column header name corresponding to each record.
    my %columnHeaderPositionHash = ();

    # This variable stores the volume name.
    my $volName = "";

    # This variable stores the pool name.
    my $poolName = "";

    $logObj->info("Reading raw configuration data for Volume resource.");

    open(CONF_DUMP, $rawConfFile) or die $logObj->error("Not able to open the file: [$rawConfFile].");

    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        if (/^(\s*)(.+)>>vol_list(\s*)$/)
        {
            $isHeaderInfo = 1;
        }
        elsif (/^(\s*)(.+)>>(\s*)$/)
        {
            $isDataStart = 0;
        }
        elsif (1 == $isHeaderInfo)
        {
            $dataParsingObj->getColumnDataPosition($_, \%columnHeaderPositionHash);

            $isHeaderInfo = 0;
            $isDataStart = 1;
        }
        elsif (1 == $isDataStart)
        {
            $dataParsingObj->getColumnDataValues($_, \%columnHeaderPositionHash, \@columnNumberList, \@columnValueList);

            $volName = @columnValueList[0];
            $volName =~ s/ /_/g;

            $poolName = @columnValueList[2];
            $poolName =~ s/ /_/g;

            my $totalCapacity = convertTBCapToGB(@columnValueList[1]);
            my $usedCapacity = convertTBCapToGB(@columnValueList[3]);

            print $CONF_HANDLE "R:ixVolume#$storageName^$volName\n";
            print $CONF_HANDLE "a:name=$storageName^$volName\n";
            print $CONF_HANDLE "a:totalCapacityGB=$totalCapacity\n";
            print $CONF_HANDLE "a:usedCapacityGB=$usedCapacity\n";
            print $CONF_HANDLE "r:ixPool#$storageName^$poolName\n";
            print $CONF_HANDLE "r:ixStorage#$storageName\n";
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    close (CONF_DUMP);
}

# This function is used to process Pool resource raw conf data and dump it in final MARS format.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   1 if Error
sub processPoolConfData
{
    $rawConfFile = $tmpDataDir."/$startTime/xivPoolConf.dump";

    # This array is used to store the required column numbers of a resource.
    my @columnNumberList = (0, 1, 2, 3, 4, 5, 6, 7);

    # This array is used to store the column value of each column of a resource.
    my @columnValueList = ();

    # This hash is used to store the name of the resource and the column header name corresponding to each record.
    my %columnHeaderPositionHash = ();

    # This variable stores the Pool Name.
    my $poolName = "";

    $logObj->info("Reading raw configuration data for Pool resource.");

    open(CONF_DUMP, $rawConfFile) or die $logObj->error("Not able to open the file: [$rawConfFile].");

    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        if (/^(\s*)(.+)>>pool_list(\s*)$/)
        {
            $isHeaderInfo = 1;
        }
        elsif (/^(\s*)(.+)>>(\s*)$/)
        {
            $isDataStart = 0;
        }
        elsif (1 == $isHeaderInfo)
        {
            $dataParsingObj->getColumnDataPosition($_, \%columnHeaderPositionHash);

            $isHeaderInfo = 0;
            $isDataStart = 1;
        }
        elsif (1 == $isDataStart)
        {
            $dataParsingObj->getColumnDataValues($_, \%columnHeaderPositionHash, \@columnNumberList, \@columnValueList);

            $poolName = @columnValueList[0];

            # Replace space by underscore in pool name.
            $poolName =~ s/ /_/g;

            my $totalCapacity = convertTBCapToGB(@columnValueList[1]);
            my $hardCapacity = convertTBCapToGB(@columnValueList[2]);
            my $snapshotCapacity = convertTBCapToGB(@columnValueList[3]);
            my $availableCapacity = convertTBCapToGB(@columnValueList[4]);
            my $usedVolumeCapacity = convertTBCapToGB(@columnValueList[5]);
            my $usedSnapshotCapacity = convertTBCapToGB(@columnValueList[6]);

            print $CONF_HANDLE "R:ixPool#$storageName^$poolName\n";
            print $CONF_HANDLE "a:name=$storageName^$poolName\n";
            print $CONF_HANDLE "a:totalCapacityGB=$totalCapacity\n";
            print $CONF_HANDLE "a:hardCapacity=$hardCapacity\n";
            print $CONF_HANDLE "a:snapshotCapacity=$snapshotCapacity\n";
            print $CONF_HANDLE "a:availableCapacity=$availableCapacity\n";
            print $CONF_HANDLE "a:usedVolumeCapacity=$usedVolumeCapacity\n";
            print $CONF_HANDLE "a:usedSnapshotCapacity=$usedSnapshotCapacity\n";
            print $CONF_HANDLE "a:lockStatus=@columnValueList[7]\n";
            print $CONF_HANDLE "r:ixStorage#$storageName\n";
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    close (CONF_DUMP);
}

# This function is used to process Disk resource raw conf data and dump it in final MARS format.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   1 if Error
sub processDiskConfData
{
    $rawConfFile = $tmpDataDir."/$startTime/xivDiskConf.dump";

    # This array is used to store the required column numbers of a resource.
    my @columnNumberList = (0, 1, 3, 5, 6, 7, 8);

    # This array is used to store the column value of each column of a resource.
    my @columnValueList = ();

    # This hash is used to store the name of the resource and the column header name corresponding to each record.
    my %columnHeaderPositionHash = ();

    # This variable stores the disk name.
    my $diskName = "";

    $logObj->info("Reading raw configuration data for Disk resource.");

    open(CONF_DUMP, $rawConfFile) or die $logObj->error("Not able to open the file: [$rawConfFile].");

    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        if (/^(\s*)(.+)>>disk_list(\s*)$/)
        {
            $isHeaderInfo = 1;
        }
        elsif (/^(\s*)(.+)>>(\s*)$/)
        {
            $isDataStart = 0;
        }
        elsif (1 == $isHeaderInfo)
        {
            $dataParsingObj->getColumnDataPosition($_, \%columnHeaderPositionHash);

            $isHeaderInfo = 0;
            $isDataStart = 1;
        }
        elsif (1 == $isDataStart)
        {
            $dataParsingObj->getColumnDataValues($_, \%columnHeaderPositionHash, \@columnNumberList, \@columnValueList);

            $diskName = @columnValueList[0];

            # Replace space by underscore in disk name.
            $diskName =~ s/ /_/g;

            my $totalCapacity = convertTBCapToGB(@columnValueList[2]);

            print $CONF_HANDLE "R:ixDisk#$storageName^$diskName\n";
            print $CONF_HANDLE "a:name=$storageName^$diskName\n";
            print $CONF_HANDLE "a:status=@columnValueList[1]\n";
            print $CONF_HANDLE "a:totalCapacityGB=$totalCapacity\n";
            print $CONF_HANDLE "a:model=@columnValueList[3]\n";
            print $CONF_HANDLE "a:size=@columnValueList[4]\n";
            print $CONF_HANDLE "a:serialNumber=@columnValueList[5]\n";
            print $CONF_HANDLE "a:firmware=@columnValueList[6]\n";
            print $CONF_HANDLE "r:ixStorage#$storageName\n";
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    close (CONF_DUMP);
}

# This function is used to process Local FC Port resource raw conf data and dump it in final MARS format.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   1 if Error
sub processLocalFcPortConfData
{
    $rawConfFile = $tmpDataDir."/$startTime/xivLocalFCPortConf.dump";

    # This array is used to store the required column numbers of a resource.
    my @columnNumberList = (0, 1, 2, 3, 4, 7, 8, 9, 10, 11);

    # This array is used to store the column value of each column of a resource.
    my @columnValueList = ();

    # This hash is used to store the name of the resource and the column header name corresponding to each record.
    my %columnHeaderPositionHash = ();

    # This variable stores Local FC Port name.
    my $localFcPort = "";

    $logObj->info("Reading raw configuration data for Local FC Port resource.");

    open(CONF_DUMP, $rawConfFile) or die $logObj->error("Not able to open the file: [$rawConfFile].");

    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        if (/^(\s*)(.+)>>fc_port_list(\s*)$/)
        {
            $isHeaderInfo = 1;
        }
        elsif (/^(\s*)(.+)>>(\s*)$/)
        {
            $isDataStart = 0;
        }
        elsif (1 == $isHeaderInfo)
        {
            $dataParsingObj->getColumnDataPosition($_, \%columnHeaderPositionHash);

            $isHeaderInfo = 0;
            $isDataStart = 1;
        }
        elsif (1 == $isDataStart)
        {
            $dataParsingObj->getColumnDataValues($_, \%columnHeaderPositionHash, \@columnNumberList, \@columnValueList);

            $localFcPort = @columnValueList[0];

            # Replace space by underscore in local FC port name.
            $localFcPort =~ s/ /_/g;

            print $CONF_HANDLE "R:ixLocalFcPort#$storageName^$localFcPort\n";
            print $CONF_HANDLE "a:name=$storageName^$localFcPort\n";
            print $CONF_HANDLE "a:status=@columnValueList[1]\n";
            print $CONF_HANDLE "a:isFunctional=@columnValueList[2]\n";
            print $CONF_HANDLE "a:wwpn=@columnValueList[3]\n";
            print $CONF_HANDLE "a:id=@columnValueList[4]\n";
            print $CONF_HANDLE "a:currentRate=@columnValueList[5]\n";
            print $CONF_HANDLE "a:state=@columnValueList[6]\n";
            print $CONF_HANDLE "a:linkType=@columnValueList[7]\n";
            print $CONF_HANDLE "a:errorCount=@columnValueList[8]\n";
            print $CONF_HANDLE "a:activeFirmware=@columnValueList[9]\n";
            print $CONF_HANDLE "r:ixStorage#$storageName\n";
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    close (CONF_DUMP);
}

# This function is used to process Host FC Port resource raw conf data and dump it in final MARS format.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   1 if Error
sub processHostFcPortConfData
{
    # This array is used to store the required column numbers of a resource.
    my @columnNumberList = (0, 2);

    # This array is used to store the column value of each column of a resource.
    my @columnValueList = ();

    # This hash is used to store the name of the resource and the column header name corresponding to each record.
    my %columnHeaderPositionHash = ();

    # This variable stores host FC Port name.
    my $hostFcPort = "";

    # This variable stores host name.
    my $hostName = "";

    $rawConfFile = $tmpDataDir."/$startTime/xivHostConf.dump";

    $logObj->info("Reading raw configuration data for Host FC Port resource.");

    open(CONF_DUMP, $rawConfFile) or die $logObj->error("Not able to open the file: [$rawConfFile].");

    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        if (/^(\s*)(.+)>>host_list(\s*)$/)
        {
            $isHeaderInfo = 1;
        }
        elsif (/^(\s*)(.+)>>(\s*)$/)
        {
            $isDataStart = 0;
        }
        elsif (1 == $isHeaderInfo)
        {
            $dataParsingObj->getColumnDataPosition($_, \%columnHeaderPositionHash);

            $isHeaderInfo = 0;
            $isDataStart = 1;
        }
        elsif (1 == $isDataStart)
        {
            $dataParsingObj->getColumnDataValues($_, \%columnHeaderPositionHash, \@columnNumberList, \@columnValueList);

            $hostName = @columnValueList[0];

            # Replace space by underscore in local FC port name.
            $hostName =~ s/ /_/g;

            my @fcPortlist = split(/,/, @columnValueList[1]);

            foreach (@fcPortlist)
            {
                $hostFcPort = $_;

                print $CONF_HANDLE "R:ixHostFcPort#$storageName^$hostFcPort\n";
                print $CONF_HANDLE "a:name=$storageName^$hostFcPort\n";
                print $CONF_HANDLE "r:ixHost#$storageName^$hostName\n";
                print $CONF_HANDLE "r:ixStorage#$storageName\n";
            }
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    close (CONF_DUMP);
}

# This function is used to process LUN resource raw conf data and dump it in final MARS format.
#
# @affected global variables :
#   $rawConfFile
#
# @return :
#   0 if Success
#   1 if Error
sub processLunConfData
{
    # This array is used to store the required column numbers of a resource.
    my @columnNumberList = (1, 2, 4, 5);

    # This array is used to store the column value of each column of a resource.
    my @columnValueList = ();

    # This hash is used to store the name of the resource and the column header name corresponding to each record.
    my %columnHeaderPositionHash = ();

    # This variable stores host name.
    my $hostName = "";

    $rawConfFile = $tmpDataDir."/$startTime/xivLunConf.dump";

    $logObj->info("Reading raw configuration data for LUN resource.");

    open(CONF_DUMP, $rawConfFile) or die $logObj->error("Not able to open the file: [$rawConfFile].");

    while (<CONF_DUMP>)
    {
        # Remove the new line character.
        $_ =~ s/\r\n//g;
        $_ =~ s/\n//g;

        if (/^(\s*)(.+)>>mapping_list(\s*)host(=)(")(.+)(")(\s*)$/)
        {
            $isHeaderInfo = 1;
            $hostName = $6;
        }
        elsif (/^(\s*)(.+)>>(\s*)$/)
        {
            $isDataStart = 0;
        }
        elsif (/^(\s*)No Mappings(\s*)$/)
        {
            $isHeaderInfo = 0;
        }
        elsif (1 == $isHeaderInfo)
        {
            $dataParsingObj->getColumnDataPosition($_, \%columnHeaderPositionHash);

            $isHeaderInfo = 0;
            $isDataStart = 1;
        }
        elsif (1 == $isDataStart)
        {
            $dataParsingObj->getColumnDataValues($_, \%columnHeaderPositionHash, \@columnNumberList, \@columnValueList);

            my $size = convertTBCapToGB(@columnValueList[1]);

            print $CONF_HANDLE "R:ixLun#$storageName^@columnValueList[0]\n";
            print $CONF_HANDLE "a:name=$storageName^@columnValueList[0]\n";
            print $CONF_HANDLE "a:volume=$storageName^@columnValueList[0]\n";
            print $CONF_HANDLE "a:host=$storageName^$hostName\n";
            print $CONF_HANDLE "a:size=$size\n";
            print $CONF_HANDLE "a:serialNumber=@columnValueList[2]\n";
            print $CONF_HANDLE "a:locked=@columnValueList[3]\n";
            print $CONF_HANDLE "r:ixHost#$storageName^$hostName\n";
            print $CONF_HANDLE "r:ixVolume#$storageName^@columnValueList[0]\n";
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    close (CONF_DUMP);
}

# This function is used to convert a capacity in TB unit to capacity in GB unit.
#
# @affected global variables :
#   None
#
# @param :
#   $_[0] - [In] Capacity which need to be converted to GB.
#
# @return :
#   $capInGB - Capacity in GB.
sub convertTBCapToGB
{
    # Read the input parameter.
    my $inputCapacity = $_[0];

    # Capacity in Bytes.
    my $capInGB = $inputCapacity;

    if ($inputCapacity =~ /^(\s*)(.+)(\s*)(?i)(TB)$/)
    {
        $capInGB = $2 * 1024;
    }

    return $capInGB;
}


# This function is used to de-initialize the environment.
#
# @affected global variables :
#   $CONF_HANDLE
#
# @return :
#   None
sub deInit
{
    close($CONF_HANDLE);

}

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