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

# This File contains all the functions which are common to all the other file.

# Name of the Package.
package commonModule;

# It is used for strict compilation.
use strict;

# It helps in debugging. 
use warnings;

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

# It is used here for creating Directories.
use File::Path;

# These are used to get the current date and time.
use Time::HiRes qw(gettimeofday);
use POSIX "strftime";

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

# The Exporter module implements an import method which allows a module to export functions and variables
use Exporter;
our @ISA= qw( Exporter );

# These are exported by default.
our @EXPORT = qw( readAppPropertyFile getPropertyFileName );

# ----------------------------------------------------------------------------------------------------------------------------------------------------
# GLOBAL Variables
# ----------------------------------------------------------------------------------------------------------------------------------------------------

# This variable is used to store the path of MARS properties files. It is required to read the the Eternus Storage credentials from the .properties
# file specific to the input Eternus IP address.
my $propFilePath = "";

# This variable is used to store the complete name of log file.
my $logFile = "";

# This variable is used to store the complete name of .properties file which corresponds to the input Eternus IP address.
my $propFileName = "";

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

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

# This variable is used to store the file handle of log file.
my $LOG_HANDLE;

# 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]  [Eternus-<IP Address>] [Verifier|Conf|Perf] <Log message>
#
# @param :
#   $_[0] - Log message.
#
# @affected global variables :
#   None
#
# @return :
#   Nothing
sub logMsgCommon
{
    # This variable is used to store the complete path of probe specific folder in db/probe folder.
    my $eternusLogFolder = "";

    # This variable is used to store the base folder path on the MARS probe.
    my $baseFolder = "";

    # Set MARS base folder.
    $baseFolder = "__ROOT__";

    # Set Eternus log folder path.
    $eternusLogFolder = $baseFolder."/logs/eternusProbe";

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

    # 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 = $eternusLogFolder."/eternusProbe.".$date.".log";

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

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

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

    # Construct the final log message.
    my $finalMsg = $currentTime." [Eternus-".$eternusIpAddress."] [Comm] ".$logMsgCommon."\n";

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

    close($LOG_HANDLE);
}

# This function is used to read Eternus related information from the MARS app.properties file.
#
# @param :
#   $_[0] - [In] Path of app.properties file.
#   $_[1] - [In] Eternus Storage IP Address.
#   $_[2] - [Out] Location of Eternus module on system.
#
# @affected global variables :
#   None
#
# @return :
#   0 if found correct information.
#   1 if not found correct information.
sub readAppPropertyFile
{
    # This variable is used to store the location of Eternus runtime files.
    my $eternusRunTimeLocation = "";

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

    # Read input parameters.
    my $appPropertiesFilePath = $_[0];
    $eternusIpAddress = $_[1];

    logMsgCommon("Info: Reading file: [$appPropertiesFilePath].");
    
    # Opening the app.properties file.
    open(my $PROP_FILE, $appPropertiesFilePath) or die logMsgCommon("Error: Not able to open the file: [$appPropertiesFilePath].");

    # Loop through the content of app.properties file.
    while (<$PROP_FILE>)
    {
       # Remove the new line character.
        chomp;

       # Look for "Eternus.runtime.location" property.
        if ($_ =~ /^(\s*)Eternus.runtime.location=(\s*)(.+)(\s*)$/)
        {
            $eternusRunTimeLocation = $3;
            $_[2] = $eternusRunTimeLocation;
        }
        else
        {
            # Current line is of no use. So ignore it.
        }
    }

    if ("" eq $eternusRunTimeLocation)
    {
        logMsgCommon("Error: Eternus.runtime.location property not found in app.properties file.");
        $retVal = 1;

        goto EXIT;
    }

EXIT:

    close($PROP_FILE);

    return $retVal;
}

# This function is used to search all files present in $propFilePath folder and find the correct .properties file corresponding to input Eternus IP
# address.
#
# @param :
#   $_[0] - [In] Path of app.properties file.
#   $_[1] - [In] Eternus IP address.
#   $_[2] - [Out] Eternus properties file name.
#
# @affected global variables :
#   $propFileName
#   $eternusIpAddress
#
# @return :
#   0 if found correct .properties file
#   1 if not found correct .properties file
sub getPropertyFileName
{
    # This variable is used to store the complete name of .properties file which corresponds to the input Eternus IP address.
    my $propFileName = "";

    # It is used to get the list of all .properties files present in the "probe" folder.
    my @files = ();

    # It is used to check whether we have found the correct .properties file for the Eternus Storage.
    my $foundFile = 0;

    # Get the input parameters.
    (my $propFilePath, $eternusIpAddress, $propFileName) = @_;

    logMsgCommon("Info: Getting the list of files present in: [$propFilePath].");

    # Get the list of all .properties files.
    @files = glob($propFilePath."/*.properties");

    # Check each .properties file in the folder.
    foreach my $propFileNameInList (@files)
    {
        logMsgCommon("Info: Found properties file: [$propFileNameInList].");

        # Extract the file name from the complete file path.
        my $fileName = basename($propFileNameInList);

        # Check whether we are looking at correct .properties file.
        if ($fileName =~ /^Eternus_(\S+)_(\S+).properties$/)
        {
            # Match the given IP Address to find the correct .properties file because there could be multiple Eternus properties files present in the
            # folder.
            if ($eternusIpAddress =~ $2)
            {
                logMsgCommon("Info: Found correct properties file: [$fileName].");
                $_[2] = $propFileNameInList;

                $foundFile = 1;
                last;
            }
        }
    }

    # If we found the correct .properties file then return with Success.
    if (1 == $foundFile)
    {
        return 0;
    }
    else
    {
        return 1;
    }

}

# The file must return true as the last statement to indicate successful execution of any initialization code, so it's customary to end such a file with 1.
# unless you're sure it'll return true otherwise. But it's better just to put the 1;, in case you add more statements.
1;
