#!/usr/bin/perl
#----------------------------------------------------------------------------------------------
# pmDiff - calculate difference between successive counter values in ROP files
#
#----------------------------------------------------------------------------------------------
#
# Copyright (c) 2005 Ericsson Australia Pty Ltd
#
# This program may be used and/or copied only 
# with the prior written permission of Ericsson 
# Australia or in accordance with the terms and 
# conditions stipulated in the contract or agreement 
# under which the program has been supplied.
#
#----------------------------------------------------------------------------------------------
#
# v 1.0 28/09/2004 M. Harris    Initial Version
# v 1.1 13/05/2005 M. Harris    Remove spaces between delimeters in output
# v 1.2 23/02/2007 T. Husz      Handling of non-pm attributes in ROP files
# v 1.3 30/09/2008 T. Husz      Negative counter difference is allowed when using -neg option
# v 1.4 27/09/2010 F. Magnusson When val(n) < val(n-1) add 2^31 to val(n) to handle case when the counter has wrapped around. TR HM60157.
# v 1.5 29/12/2013 F. Magnusson Do not print the first ROP at all, instead of printing N/A 
# v 1.6 13/12/2014 F. Magnusson New option -force to diff even on counter whose name does not start with "pm"
#----------------------------------------------------------------------------------------------

use Getopt::Long;

my $version = "v1.3, 2008-09-30";

sub printUsage {

	if (@_) {print STDERR "@_\n";};
	die <<_EOTXT_;

pmDiff - calculate difference between successive counter values in ROP files

$version

usage: pmDiff

pmDiff reads counter values from stdin and outputs to stdout. It should be used in a pipeline
after pmExtract.

Note that counter values should be supplied to pmDiff in chronological order (this will 
normally be the case but if not you should insert 'sort' in the pipeline).

Options:

    -neg
           Negative counter difference is allowed, i.e. for counters split into two pm... counters.
    
    -force
           Diff even if the counter name does not start with "pm"

_EOTXT_

}

GetOptions(
	"help"         => \$help,
	"neg"          => \$neg,
	"force"        => \$force
) or printUsage("Invalid Options");

printUsage if ($help);

while (<>) {
	($tm, $mo, $ctr, $val) = split ';';

	if ($ctr =~ /^pm/ || $force) {	# eashut
	    if ($neg) {	# eashut
		  $pval = exists $prev_val{$mo}{$ctr} ? $val - $prev_val{$mo}{$ctr} : 'N/A';  
		  $prev_val{$mo}{$ctr} = $val;
		  if ($pval ne 'N/A') { print "$tm;$mo;$ctr;$pval\n";}
	    }
	    else {
	    	  #old code:
		  #$diff = exists $prev_val{$mo}{$ctr} ? $val - $prev_val{$mo}{$ctr} : -1;
		  #$pval = ($diff>=0) ? $diff : 'N/A';
		  
	    	  if (exists $prev_val{$mo}{$ctr}) {
		    	#According to 17/1551-CSX 101 09, all counters are 31 bit ==> max value is 2147483647
		    	#if the value of rop(n) is smaller than the value of rop(n-1) then probably the counter has wrapped around so we add 2147483647 to rop(n)
	    	  	if ($prev_val{$mo}{$ctr} > $val) { $val+=2147483647;}
	    	  	$pval = $val - $prev_val{$mo}{$ctr};
	    	  }
	    	  else {
	    	  	$pval = 'N/A';  
	    	  }
		  $prev_val{$mo}{$ctr} = $val;
		  if ($pval ne 'N/A') { print "$tm;$mo;$ctr;$pval\n";}
	    }
	}
	  
	else {
		  print "$tm;$mo;$ctr;$val\n";
	}
}

