#!/usr/bin/perl
use strict;
use Getopt::Long;
use LWP::Simple;
use DBI;

use constant DEBUG => 0;
use constant OK => 0;
use constant WARNING => 1;
use constant CRITICAL => 2;
use constant UNKNOWN => 3;
# use constant IAPURL => "http://200.220.227.125/middleware_iap_web/IapServlet";
use constant IAPURL => "https://www.portal-sva.vivo.com.br:4443/middleware_iap_web/IapServlet";
use constant DBCREDENFILE => "/usr/local/opmon/etc/db.php";
use constant IAPTMPDIR => "/usr/local/opmon/iap_tmp";
use constant NOERROR => 0;
use constant DBERROR => 1;
use constant IAERROR => 2;
use constant IAPDB => "iap";

# globals
our %msg;
our %dbdata;

sub main {

	my $ret;

	$ret = GetOptions("u=s" => \$msg{'user'},
	                  "p=s" => \$msg{'pass'},
	                  "t=i" => \$msg{'trap_type'},
	                  "s=i" => \$msg{'severity'},
	                  "d=s" => \$msg{'description'}
	);
	$msg{'timestamp'} = time();
	$msg{'error'} = NOERROR;

	# populate the optional parameters
	$msg{'trap_type'} = 1 unless defined($msg{'trap_type'});
	$msg{'severity'} = 1 unless defined($msg{'severity'});
 

	$ret = parse_db_credentials();
	if ($ret != OK) {
		store_msg();
	}

	if (DEBUG) {
		open(DEBUGFILE,">>/tmp/notify-iap-debug.log");
		print DEBUGFILE "\nnew message:\n";
		print DEBUGFILE "\ttimestamp: ".$msg{'timestamp'}."\n";
		print DEBUGFILE "\ttrap_type: ".$msg{'trap_type'}."\n";
		print DEBUGFILE "\tseverity: ".$msg{'severity'}."\n";
		print DEBUGFILE "\tdescription: ".$msg{'description'}."\n";
		print DEBUGFILE "\turl: ".$msg{'url'}."\n";
		close(DEBUGFILE);
	}

	convert_severity();
	$ret = concatenate_url();

	if (DEBUG) {
		print "\nnew message:\n";
		print "\ttimestamp: ".$msg{'timestamp'}."\n";
		print "\ttrap_type: ".$msg{'trap_type'}."\n";
		print "\tseverity: ".$msg{'severity'}."\n";
		print "\tdescription: ".$msg{'description'}."\n";
		print "\turl: ".$msg{'url'}."\n";
	}

	usage() if (!defined($msg{'user'}) || !defined($msg{'pass'}) || !defined($msg{'description'}));


	$ret = send_message();
	if ($ret !~  m/^-*\d+$/ || $ret < OK) {
		$msg{'error'} = IAERROR;
		store_msg();
		print "\nERROR: unexpected fault sending message. ret_code: $ret\n";
		exit(CRITICAL);
	} else {
		store_msg();
		if (DEBUG) {
			print "\nMessage sent sucessfully.\n";
		}
		exit(OK);
	}

}

# OpMon/IAP severity mapping:
#
# For OpMon the following assumption is true:
# 0- OK    1- WARNING   2- CRITICAL    3- UNKNOWN
#
# For IAP the following is true:
# 0- INDETERMINATE (Must be converted to OpMon UNKNOWN)
# 1- CRITICAL (Must be converted to OpMon CRITICAL)
# 2- MAJOR (This state is unecessary, cause we already have a CRITICAL state)
# 3- MINOR (This state is unecessary too)
# 4- WARNING (Must be converted to OpMon WARNING)
# 5- CLEAR (Must be converted to OpMon OK)
#
# Any other value passed should be interpreted as OpMon UNKNOWN
sub convert_severity {

	if ($msg{'severity'} == OK || $msg{'severity'} eq OK) {
		$msg{'severity'} = 5; # IAP CLEAR

	} elsif ($msg{'severity'} == WARNING || $msg{'severity'} eq WARNING) {
		$msg{'severity'} = 4; # IAP WARNING

	} elsif ($msg{'severity'} == CRITICAL || $msg{'severity'} eq CRITICAL) {
		$msg{'severity'} = 1; # IAP CRITICAL

	} else {
		$msg{'severity'} = 0; # IAP INDETERMINATE
	}

}

sub send_message {

	my $ret;
	$ret = get $msg{'url'};
	print "\nurl returns: $ret\n" if (DEBUG);
	$msg{'req_id'} = $ret;
	return $ret;

}

sub concatenate_url {

	my $url;

	$url  = IAPURL."?";
	$url .= "usuario=".$msg{'user'}."&";
	$url .= "senha=".$msg{'pass'}."&";
	$url .= "trap_type=".$msg{'trap_type'}."&";
	$url .= "severidade=".$msg{'severity'}."&";
	$url .= "descricao=".$msg{'description'};

	$msg{'url'} = $url;

	return OK;
}

sub store_msg {

	my $file_name;
	my $dbh;
	my $query;
	my $ret;
	my $dir;

	# maybe db is out of work, store this message in file
	if ($msg{'error'} == DBERROR) {

		$dir = IAPTMPDIR;
		if (!-d IAPTMPDIR) {

			print IAPTMPDIR." doesn't exist. Let's create it\n" if (DEBUG);

			$ret = mkdir IAPTMPDIR;
			if (!$ret) {
				print "Unable to create ".IAPTMPDIR."... lets store our msg on /tmp\n" if (DEBUG);
				$dir = "/tmp";
			} else {
				print "Directory ".IAPTMPDIR." created sucessfully\n" if (DEBUG);
			}
		}

		$file_name = "iap_error_".$msg{'timestamp'}."-".rand().".error";
		open("DBERROR",">$dir/".$file_name);
		print "timestamp: ".$msg{'timestamp'}."\n";
		print "trap_type: ".$msg{'trap_type'}."\n";
		print "severity: ".$msg{'severity'}."\n";
		print "description: ".$msg{'description'}."\n";
		print "url: ".$msg{'url'}."\n";
		print "req_id: ".$msg{'req_id'}."\n";

		close(DBERROR);

	} else {


		$dbh = DBI->connect('DBI:mysql:'.IAPDB.";host=".$dbdata{'DBHOST'},
		                    $dbdata{'DBUSER'},
		                    $dbdata{'DBPASS'});


		$query = 'insert into iap_logs values('.
		         '"'.addslashes($msg{'timestamp'}).'",'.
		         '"'.addslashes($msg{'trap_type'}).'",'.
		         '"'.addslashes($msg{'severity'}).'",'.
		         '"'.addslashes($msg{'description'}).'",'.
		         '"'.addslashes($msg{'url'}).'",'.
		         '"'.addslashes($msg{'req_id'}).'")';
		$ret = $dbh->do($query);
		$dbh->disconnect();

		if ($ret == undef) {
			print "Error executing query... storing message at FS level\n";
			$msg{'error'} = DBERROR;
			store_msg();
		}

	}

}

sub addslashes {

	my $text;
	$text = shift;
	$text =~ s/\\/\\\\/g;
	$text =~ s/'/\\'/g;
	$text =~ s/"/\\"/g;
	$text =~ s/\\0/\\\\0/g;
	return $text;

}

# populate %dbdata{'DBUSER'}, %dbdata{'DBPASS'} and %dbdata{'DBHOST'}
sub parse_db_credentials {

	if (!-f DBCREDENFILE) {
		$msg{'error'} = DBERROR;
		return CRITICAL;
	}

	open('DBFILE',DBCREDENFILE);
	while(<DBFILE>) {
		if (m/.*\$(.+) *\t*="(.+)" *\t*;$/) {
			$dbdata{$1} = $2;
		}
	}
	close(DBFILE);

	if (!defined($dbdata{'DBUSER'}) || !defined($dbdata{'DBPASS'}) || !defined($dbdata{'DBHOST'})) {
		if (DEBUG) {
			print "Unexpected error occured when parsing db asccess credentials data\n";
		}
		$msg{'error'} = DBERROR;
		return CRITICAL;
	}

	if (DEBUG) {
		print "\ndb access data:\n";
		print "\tDBUSER = ".$dbdata{'DBUSER'}."\n";
		print "\tDBPASS = ".$dbdata{'DBPASS'}."\n";
		print "\tDBHOST = ".$dbdata{'DBHOST'}."\n";
	}

	return OK;
}


sub usage {

	print "Usage:\n";
	print "\t./notify-vivo-iap -u <user> -p <password> [-t <trap_type>] [-s <severity>] -d <description>\n";
	print "\tDefault value for trap_type and severity is 1\n";
	exit(OK);

}

&main();
