#!/usr/bin/perl
################################################################################
# Filename: ./src/base/bin/qrm-metric-agent
# 
# The contents of this file are subject to the Qlusters Public License
# Version 1.1 (the License); you may not use this file except in compliance
# with the License.
# You may obtain a copy of the License at
# http://www.openqrm.org/content/view/33/69/.
# 
# Software distributed under the License is distributed on an AS IS basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
# the specific language governing rights and limitations under the License.
# 
# The Original Code is openQRM.
# 
# The Initial Developer of the Original Code is Qlusters Corporation. Portions
# created by Qlusters Corporation are Copyright (C) 2003-2005. All Rights
# Reserved.
# 
# Contributor(s):
# 
# Description:
# 
# Comments:
################################################################################
#NOTE - 
#     STDOUT is writing to /tmp/policy.out
#     STDERR is writing to /tmp/policy.error

my $progname = $0; $progname =~ s@.*/@@g;
my $min_send_interval;
my $sample_interval = 1;
my $average_size;
my $detla = 1;
my $type;
my $metric;
my $count = 0;
my $user = "qrm";
my $passwd = "qrm";
my $server; #your qrm server
my $id = 01;   #node value or ve name
my $wget = "/usr/bin/wget -q -O /dev/null";
my $port = 80;

#Grab the variables from command line
foreach (@ARGV) {
$count ++;
($_ =~ /--sample-program/) && ($sample_program = $ARGV[$count]);
($_ =~ /--min-send-interval/) && ($min_send_interval = $ARGV[$count]);
($_ =~ /--sample-interval/) && ($sample_interval = $ARGV[$count]);
($_ =~ /--average-size/) && ($average_size = $ARGV[$count]);
($_ =~ /--delta/) && ($delta = $ARGV[$count]);
($_ =~ /--type/) && ($type = $ARGV[$count]);
($_ =~ /--metric-name/) && ($metric = $ARGV[$count]);
($_ =~ /--user/) && ($user = $ARGV[$count]);
($_ =~ /--password/) && ($password = $ARGV[$count]);
($_ =~ /--server/) && ($server = $ARGV[$count]);
($_ =~ /--id/) && ($id = $ARGV[$count]);
}

#catch user input errors or missing requirements
unless ($sample_program && $min_send_interval && $type && $metric && $id && $server) {
print "Usage: $program [OPTIONS]\n";
print "Helper application to send metrics values based on a simple sampling script\n";
print "\n";
print "OPTIONS are: \n";
print "\t--sample-program <sampling script>     -- name of sampling script\n";
print "\t--min-send-interval <sec>              -- minimal interval to send metrics\n";
print "\t--metric-name <name>                   -- metric name\n";
print "\t--type <vm|ve>                         -- entity type this metric refers to \n";
print "\t--id <vm|ve id>                        -- id of virtual machine / virtual environment\n";
print "\t--server <ip|hostname>                 -- ip or hostname of qrm server\n";
print "\t--user <name>                          -- user name\n";
print "\t--password <password>                  -- password\n";
print "\t[--sample-interval <sec>]              -- interval of calling the sample script (default is 1)\n";
print "\t[--average-size  <size>]               -- number of samlings to average over (default is min-send-interval)\n";
print "\t[--delta <delta>]                      -- delta of average difference that causes a send (default is 1)\n"; 
exit;
}  

#set default values if they are not defined
($average_size) || ($average_size = $min_send_interval);

#pass values to PolicyMonitor Sub Routine
&PolicyMonitor($sample_program, $min_send_interval, $sample_interval, $average_size, $delta);

sub PolicyMonitor () 
{
     my $program = $_[0];
     my $send_interval = $_[1];
     my $sample = $_[2];
     my $user_defined_average = $_[3];
     my $delta_value = $_[4];
     my $delta2 =  0;
     my $count2 = 0;
     my $subtract_value = 0;
     my $average = 0;
     my $sum = 0;
     my @array = ();

     #daemonize the process 
     &daemonize;

     #our infinite loop
     while(1) 
     {   
     	#set counter
	($count2 < $send_interval) && $count2 ++;
	
	#Run the local get value program
	$value = `$program`;
	
	#determine how to manipulate most current value and sum values
	(($#array + 1) == $user_defined_average) && ($subtract_value = shift(@array));	
	push (@array, $value);
	$sum = (($sum - $subtract_value) + $value);
	
	#test if we're greater then minimum send interval
	if ($count2 == $send_interval) {	
		$average = $sum / ($#array + 1);
	
		#check if delta is equal to user defined value and send to qrm
		$actual_delta = abs($old_average - $average); 
		if ($actual_delta >= $delta_value) {

			#send to qrm
			&NotifyQrm($wget, $server, $user, $passwd, $server_name, $type, $id, $metric, $average);
			$count2 = 0;
			$old_average = $average;
		}
	}
	
	#loop every $value seconds
        sleep($sample);     
	}
}

sub daemonize {
    #chdir '/'                 or die "Can't chdir to /: $!";
    open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
    open STDOUT, '>/tmp/policy.out' or die "Can't write to /tmp/policy.out: $!";
    open STDERR, ">/tmp/policy.error" or die "Can't write to /tmp/policy.error: $!";
    defined(my $pid = fork)   or die "Can't fork: $!";
    exit if $pid;
    setsid                    or die "Can't start a new session: $!";
    umask 0;
}

sub NotifyQrm {
    my $wget = $_[0];
    my $server = $_[1];
    my $user = $_[2];
    my $passwd = $_[3];
    my $server_name = $_[4];
    my $type = $_[5];
    my $id = $_[6];
    my $metric = $_[7];
    my $value = $_[8];
    my $idReq;
    if ($type == "vm") {
	$idReq="--internal_ve_id";
    } else {
	$idReq="--internal_vm_id";
    }
    my $command_string = "$wget http://${server}:${port}/cli?arg=metric&arg=add&arg=-m&arg=$metric%3D$value&arg=-u&arg=$user&arg=-p&arg=$password&$idReq=$id";
    
    #uncomment here if you want to debug the command string being sent to qrm
    #print STDOUT "$command_string\n";
    system($command_string) && die "Couldn't run wget: $!\n";
}
