#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html

# Script to demonstrate how to parse out the event info that comes from a
# Condition that is watching another Condition in a hierarchical cluster environment.

# To use this script, create a Response that invokes this script with a log file name as the input.
# Then associate the Response with a Condition that is watching Conditions on other
# nodes.  When the Conditions occur, this script will wall the relevant event information.

# This info that is passed into this sample is structured as follows:
#  EMS Condition/Event:
#   $ENV{ERRM_COND_NAME}
#   $ENV{ERRM_TYPEID}
#     ...
#   $ENV{ERRM_NODE_NAME} -->  SN
#   $ENV{ERRM_RSRC_NAME} -->  SN Condition
#   $ENV{ERRM_VALUE}     -->  SN Event:
#                              $Occurred
#                              $ErrNum
#                                ...
#                              $NodeName     -->  Leaf Node:
#                              $ResourceName -->   Resource
#                              $Attribute 1  -->    Attr 1
#                              $Attribute 2  -->    Attr 2

use strict;
use Getopt::Std;
use POSIX qw(strftime);
use File::Path;


# Convert Severity and Type environment variables from integers to strings
my @COND_SEVERITY = qw(Informational Warning Critical);
my @TYPE          = ('Event', 'Rearm event');
my $severity      = $COND_SEVERITY[ $ENV{ERRM_COND_SEVERITYID} ];
my $type          = $TYPE[ $ENV{ERRM_TYPEID} ];

my $filename = shift;

# Parse the ERRM_VALUE attribute, which will contain the EventOccurred structured data variable from the Condition class
# The fields in this structured data variable are documented below where we parse them out.
my $event = $ENV{ERRM_VALUE};
$event =~ s/^\[(.*)\]$/$1/;    # SD variables have square brackets around them

# This parse the LastEvent
my (                           # split the SD into the following fields:
    $Occurred,        # One if the condition has been triggered
    $ErrNum,          # Non-zero if there was in error in the event registration
    $ErrMsg,          # The string msg related to ErrNum
    $EventFlags,      # Bit mask giving some additional info about the event
    $EventTime,       # Time of event expressed in seconds since 1/1/1970
    $EventTimeMicros, # Number of microseconds past EventTime
    $ResourceHandle, # Binary address of the RMC resource that caused the condition to be triggered
    $NodeName, # The node on which the event occurred.  For conditions that use the management domain scope (4),
               # this will be the leaf node.  For conditions that use the local scope (e.g. NodeReachability),
               # this will be the FMS.
    $NumAttrs, # Number of attr values from the resource returned in this event
    $NumAttrsInExpr, # How many of the above were attributes in the event expression
    $IndexForAttrs, # The starting index of the array of values.  Until new fixed fields are added
                    # to LastEvent, this will be the element right after this one.
    $AttrArray      # This list of attribute names, types, and values
) = split(/,/, $event, 12);

my @attrArray = split(/,/, $AttrArray); # Note: parsing this way does not support SDs or SD Arrays that may be in this list

my ($ResourceName, $valuesMsg);
my $j = 0;                              # index into attrArray
for (my $i = 0 ; $i < $NumAttrs ; $i++) {
    my $attrName = $attrArray[ $j++ ];
    my $attrType = $attrArray[ $j++ ]; # Types <= 8 are "simple" types. Types > 8 are SDs and arrays.
    my $attrValue = $attrArray[ $j++ ];
    if ($attrName eq '"Name"') { $ResourceName = $attrValue; }
    $valuesMsg .= "    Attribute Value $i:  $attrName = $attrValue\n";
}
if (!length($ResourceName)) { $ResourceName = '(unknown)'; }

my $msg = "=============================================================================\n";
$msg .= "  Time:  " . convertTime($EventTime) . " \n";
$msg .= "  MN Condition:  $ENV{ERRM_COND_NAME}\n";
$msg .= "  Severity:  $severity\n";
$msg .= "  Event Type:  $type\n";
$msg .= "  SN Condition:  $ENV{ERRM_RSRC_NAME}\n";
$msg .= "  SN:  $ENV{ERRM_NODE_NAME}\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= "  Node:  $NodeName\n";
$msg .= "  Resource Name:  $ResourceName\n";
if (length($valuesMsg)) {
    $msg .= "  Attributes:\n";
    $msg .= $valuesMsg;
}

# Skipped the following:  $ERRM_EXPR $ERRM_RSRC_CLASS_PNAME $ERRM_DATA_TYPE $ERRM_NODE_NAMELIST $ERRM_RSRC_TYPE
#$str = escape_chars($str);
if (open(FILE, ">>$filename")) {
    print FILE "$msg\n";
    close(FILE);
}

exit;


# convert time string
sub convertTime {
    my ($seconds, $micro) = split(/\./, $_[0]);
    return strftime("%A %D %T", localtime($seconds));
}