#! /usr/bin/perl -w
###################################################################
# Oreon is developped with GPL Licence 2.0 
#
# GPL License: http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#
# Developped by : Julien Mathis - Romain Le Merlus 
#                 Mathavarajan Sugumaran
#
###################################################################
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
#    For information : contact@merethis.com
####################################################################
#
# Plugin init
#

use strict;
use DBI;
use vars qw($PROGNAME);
use Getopt::Long;
use vars qw($opt_V $opt_H $opt_h $opt_i);
use lib "/usr/share/nagios/plugins";
use utils qw($TIMEOUT %ERRORS &print_revision &support);

## For Debug mode = 1
my $debug = 0;

sub print_help ();
sub print_usage ();

Getopt::Long::Configure('bundling');
GetOptions
    ("h" => \$opt_h, 
     "help" => \$opt_h,
     "V" => \$opt_V, 
     "i=s" => \$opt_i);

###########################
## Set Database information
###########################
use vars qw($mysql_database_oreon $mysql_database_ods $mysql_host $mysql_user $mysql_passwd);
require "/etc/centreon/conf.pm";

my $dbh  = DBI->connect("DBI:mysql:database=$mysql_database_oreon;host=$mysql_host","$mysql_user", "$mysql_passwd",{'RaiseError' => 1});
my $dbh2 = DBI->connect("DBI:mysql:database=$mysql_database_ods;host=$mysql_host","$mysql_user", "$mysql_passwd",{'RaiseError' => 1});

if ($opt_V) {
    print_revision($PROGNAME,'$Revision: 0.1 $');
    exit $ERRORS{'OK'};
}

if ($opt_h) {
    print_help();
    exit $ERRORS{'OK'};
}

my $result;
my $warning;
my $critical;
my $metric_id;

sub return_value($$$$){
    
    my $sth_output = $dbh->prepare("SELECT meta_display FROM `meta_service` WHERE `meta_id` = '".$_[3]."'");
    if (!$sth_output->execute) {die "Error:" . $sth_output->errstr . "\n";}
    my $sth_output_data = $sth_output->fetchrow_hashref();
    my $output = $sth_output_data->{'meta_display'};
    if (defined($output) && $output) {
	    $output =~ s/\%d/$result/g;
	}
    if (defined($warning) && defined($critical) && $warning ne $critical){
		if ($warning < $critical){ # Bon sens
		    if ($result < $warning){
			    if ($output) {
			    	print $output. "|value=" . $result . ";".$warning.";".$critical."\n";
			    } else {
					print "OK result : " . $result . "|value=" . $result . ";".$warning.";".$critical."\n";
				}
				exit $ERRORS{'OK'};
		    } elsif (($result >= $warning) && ($result < $critical)){
			    if ($output) {
			    	print $output. "|value=" . $result . ";".$warning.";".$critical."\n";
			    }else {
					print "WARNING result : " . $result . "|value=" . $result . ";".$warning.";".$critical."\n";
				}
				exit $ERRORS{'WARNING'};
		    } elsif ($result >= $critical){
		        if ($output) {
				   	print $output. "|value=" . $result . ";".$warning.";".$critical."\n";
		    	}else {
					print "CRITICAL result : " . $result . "|value=" . $result . ";".$warning.";".$critical."\n";
				}
				exit $ERRORS{'CRITICAL'};
		    }
		} else { # sens inverse
		    if ($result < $critical){
		    	if ($output) {
			    	print $output. "|value=" . $result . ";".$warning.";".$critical."\n";
			    }else {
		   			 print "CRITICAL result : " . $result . "|value=" . $result . ";".$warning.";".$critical."\n";	    
		   		}
				exit $ERRORS{'CRITICAL'};
		    } elsif ($result >= $critical && $result < $warning){
		    	if ($output) {
			    	print $output. "|value=" . $result . ";".$warning.";".$critical."\n";
			    }else {
					print "WARNING result : " . $result . "|value=" . $result . ";".$warning.";".$critical."\n";
				}
				exit $ERRORS{'WARNING'};
		    } elsif ($result >= $warning){
		    	if ($output) {
			    	print $output. "|value=" . $result . ";".$warning.";".$critical."\n";
			    }else {
					print "OK result : " . $result . "|value=" . $result . ";".$warning.";".$critical."\n";
				}
				exit $ERRORS{'OK'};
		    } else{
		       	if ($output) {
			    	print $output. "|value=" . $result . ";".$warning.";".$critical."\n";
			    }else {
					print "OK result : " . $result . "|value=" . $result . ";".$warning.";".$critical."\n";
				}
				exit $ERRORS{'OK'};
		    }
		}
    } elsif (!defined($warning) || !defined($critical)) {
		if ($output) {
	    	if ($output) {
		    	print $output. "|value=" . $result . "\n";
		    } else {
				print "OK result : " . $result . "|value=" . $result . "\n";
			}
		}
		exit $ERRORS{'OK'};
    } else {
		print "ERROR : warnig level = critical level";
		exit $ERRORS{'CRITICAL'};
    }
}

my $ref;
my $svc_id;
my $metric;
my $host_id;

## Get Value by metric Option

sub get_value_in_database_metric_id($$$$){
    ## Get last entry in perfparse database for this service
    my $str = "SELECT value FROM data_bin WHERE id_metric = '".$metric_id."' ORDER BY ctime DESC LIMIT 1";
    if ($debug) {print $str . "\n";}
    my $sth_deb2 = $dbh2->prepare($str);
    if (!$sth_deb2->execute) {die "Error:" . $sth_deb2->errstr . "\n";}
    my $sth_deb2_data = $sth_deb2->fetchrow_hashref();
    return $sth_deb2_data->{'value'};
}

## Get value For Regexp Options

sub get_value_in_database($$$$$){

    my $str;
    ## Get hostname and service description for perfparse request
    
    $str = "SELECT host_name,service_description FROM host,host_service_relation,service WHERE host.host_id = host_service_relation.host_host_id AND 
service.service_id = host_service_relation.service_service_id AND service.service_id = '".$svc_id."'";
    
    if ($debug) {print $str . "\n";}
    my $host_data = $dbh->prepare($str);
    if (!$host_data->execute) {die "Error:" . $host_data->errstr . "\n";}
    my $data = $host_data->fetchrow_hashref();
    
    ## Get last entry in perfparse database for this service
    my $sth_deb2 = $dbh2->prepare("SELECT value FROM metrics m, data_bin d, index_data i WHERE i.host_name = '".$data->{'host_name'}."' AND i.service_description = '".$data->{'service_description'}."' AND and m.index_id=i.id AND m.metric_id = d.id_metric AND m.metric_name = '".$metric."' ORDER BY ctime DESC LIMIT 1");
    if (!$sth_deb2->execute) {die "Error:" . $sth_deb2->errstr . "\n";}
    my $sth_deb2_data = $sth_deb2->fetchrow_hashref();
    return $sth_deb2_data->{'value'};
}

sub get_value_in_database_by_host($$$$$){

    my $str;
    
    ## Get hostname and service description for perfparse request
    
    $str = "SELECT host_name,service_description FROM host,host_service_relation,service WHERE host.host_id = host_service_relation.host_host_id AND service.service_id = host_service_relation.service_service_id AND service.service_id = '".$svc_id."'";
    if ($debug) {print $str . "\n";}
    my $host_data = $dbh->prepare($str);
    if (!$host_data->execute) {die "Error:" . $host_data->errstr . "\n";}
    my $data = $host_data->fetchrow_hashref();

    ## Get last entry in perfparse database for this service

    my $sth_deb2 = $dbh2->prepare("SELECT value FROM metrics m, data_bin d, index_data i WHERE i.host_name = '".$data->{'host_name'}."' AND i.service_description = '".$data->{'service_description'}."' AND m.index_id=i.id AND m.metric_id = d.id_metric AND m.metric_name = '".$metric."' ORDER BY ctime DESC LIMIT 1");
    if (!$sth_deb2->execute) {die "Error:" . $sth_deb2->errstr . "\n";}
    my $sth_deb2_data = $sth_deb2->fetchrow_hashref();
    return $sth_deb2_data->{'value'};
}

sub get_value_in_database_by_hg($$$$$$){
    my $str;
    ## Get hostname 
    $str = "SELECT host_name FROM host WHERE host.host_id = '".$host_id."'";
    if ($debug) {print $str . "\n";}
    my $hd = $dbh->prepare($str);
    if (!$hd->execute) {die "Error:" . $hd->errstr . "\n";}
    my $host_data = $hd->fetchrow_hashref();
   
    ## Get service description
    
    $str = "SELECT service_description FROM service WHERE service.service_id = '".$svc_id."'";
    if ($debug) {print $str . "\n";}
    my $sd = $dbh->prepare($str);
    if (!$sd->execute) {die "Error:" . $sd->errstr . "\n";}
    my $service_data = $sd->fetchrow_hashref();
    
    ## Get last entry in perfparse database for this service
    
    my $sth_deb2 = $dbh2->prepare("SELECT value FROM metrics m, data_bin d, index_data i WHERE i.host_name = '".$host_data->{'host_name'}."' AND i.service_description = '".$service_data->{'service_description'}."' AND m.index_id=i.id AND m.metric_id = d.id_metric AND m.metric_name = '".$metric."' ORDER BY ctime DESC LIMIT 1");
    if (!$sth_deb2->execute) {die "Error:" . $sth_deb2->errstr . "\n";}
    my $sth_deb2_data = $sth_deb2->fetchrow_hashref();
    return $sth_deb2_data->{'value'};
}

my $cpt = 0;
my $total = 0;
my $max = 0;
my $min = 999999999;
my $svc;
my $value = 0;
my $svc_relation2;

if ($opt_i){
    my $str;

    # get osl info
    my $sth = $dbh->prepare("SELECT calcul_type,regexp_str,warning,critical,metric, meta_select_mode FROM meta_service WHERE meta_id = '".$opt_i."'");
    if (!$sth->execute) {die "Error:" . $sth->errstr . "\n";}
    $ref = $sth->fetchrow_hashref();
    if (!defined($ref->{'calcul_type'})){
		print "Unvalidate Meta Service\n";
		exit $ERRORS{'CRITICAL'};
    }
    
    $warning = $ref->{'warning'};
    $critical = $ref->{'critical'};
    
    # Get Service List by regexp    
    if ($ref->{'meta_select_mode'} eq '2'){
	
	###############################################
	
	$str = "SELECT service_id FROM service WHERE `service_description` LIKE '".$ref->{'regexp_str'}."' AND service_activate = '1' AND service_register = '1'";
	if ($debug) {print $str . "\n";}
	$sth = $dbh->prepare($str);
	if (!$sth->execute) {die "Error:" . $sth->errstr . "\n";}
	while ($svc = $sth->fetchrow_hashref()){
		my $sth2 = $dbh->prepare("SELECT * FROM host_service_relation WHERE service_service_id = '".$svc->{'service_id'}."'");
	    if (!$sth2->execute) {die "Error:" . $sth2->errstr . "\n";}
	    my $svc_relation = $sth2->fetchrow_hashref();
	    if (defined($svc_relation->{'host_host_id'}) && $svc_relation->{'host_host_id'}){
    		#### Par Host    		
			if (defined($svc->{'service_id'})){$svc_id = $svc->{'service_id'};} else {$svc_id = $svc->{'svc_id'};}
			if (defined($ref->{'regexp_str'})){$metric = $ref->{'metric'};} else {$metric = $svc->{'metric'};}
			$value = get_value_in_database_by_host($dbh,$dbh2,$svc_id,$metric,$debug);			    
			if ($ref->{'calcul_type'} =~ "AVE"){			
			    if (defined($value) && $value){$total += $value;}
			    if ($debug) {print "total = " . $total . "  value = ".$value."\n";} 
			    $cpt++;
			    $result = $total / $cpt;
			} elsif ($ref->{'calcul_type'} =~ "SOM"){
			    if ($value){$total += $value;}
			    if ($debug){print "total = " . $total . "  value = ".$value."\n";} 
			    $result = $total;
			} elsif ($ref->{'calcul_type'} =~ "MIN"){
			    if ($debug){print " min : " . $min . "  value = ".$value."\n";} 
			    if ($value && $value <= $min){$min = $value;}
			    $result = $min;
			} elsif ($ref->{'calcul_type'} =~ "MAX"){
			    if ($debug){print "max = " . $max . "  value = ".$value."\n";}
			    if ($value && $value >= $max){$max = $value;}
			    $result = $max;
			}
		} elsif (defined($svc_relation->{'hostgroup_hg_id'}) && $svc_relation->{'hostgroup_hg_id'}) {
			### Par Hostgroup
			my $sth3 = $dbh->prepare("SELECT host_host_id FROM hostgroup_relation WHERE hostgroup_hg_id = '".$svc_relation->{'hostgroup_hg_id'}."'");
	    	if (!$sth3->execute) {die "Error:" . $sth3->errstr . "\n";}
	    	while ($svc_relation2 = $sth3->fetchrow_hashref()){
	    		if (defined($svc->{'service_id'})){
		    		$svc_id = $svc->{'service_id'};
		    	} else {
		    		$svc_id = $svc->{'svc_id'};
		    	}
		    	if (defined($ref->{'regexp_str'})){
		    		$metric = $ref->{'metric'};
		    	} else {
		    		$metric = $svc->{'metric'};
		    	}
		    	$host_id = $svc_relation2->{'host_host_id'};
		    	$value = get_value_in_database_by_hg($dbh,$dbh2,$svc_id, $host_id, $metric, $debug);			    
		    	if ($ref->{'calcul_type'} =~ "AVE"){			
					if (defined($value) && $value){
						$total += $value;
					}
					if ($debug) {print "total = " . $total . "  value = ".$value."\n";} 
					$cpt++;
		    	} elsif ($ref->{'calcul_type'} =~ "SOM"){
					if ($value){
						$total += $value;
					}
					if ($debug){print "total = " . $total . "  value = ".$value."\n";} 
		    	} elsif ($ref->{'calcul_type'} =~ "MIN"){
					if ($debug){print " min : " . $min . "  value = ".$value."\n";} 
					if ($value && $value <= $min){
						$min = $value;
					}
		    	} elsif ($ref->{'calcul_type'} =~ "MAX"){
					if ($debug){print "max = " . $max . "  value = ".$value."\n";}
					if ($value && $value >= $max){
					$max = $value;
				}
			}
		}
		if ($ref->{'calcul_type'} =~ "AVE"){
		    $result = $total / $cpt;
		} elsif ($ref->{'calcul_type'} =~ "SOM"){
		    $result = $total;
		} elsif ($ref->{'calcul_type'} =~ "MIN"){
		    $result = $min;
		} elsif ($ref->{'calcul_type'} =~ "MAX"){
		    $result = $max;
		}
	    }
	}
	return_value($result, $warning, $critical, $opt_i);
	###############################################
    } else {
		$sth = $dbh->prepare("SELECT metric_id FROM `meta_service_relation` WHERE meta_id = '".$opt_i."'");
		if (!$sth->execute) {die "Error:" . $sth->errstr . "\n";}
		if ($ref->{'calcul_type'} =~ "AVE"){
		 	if (!$sth->rows) {
	            print "no result in table meta_service_relation for id $opt_i\n";
	        	exit $ERRORS{'UNKNOWN'};
	        }
		    while ($svc = $sth->fetchrow_hashref()){
			if (defined($svc->{'metric_id'})){$metric_id = $svc->{'metric_id'};}
			$value = get_value_in_database_metric_id($dbh,$dbh2,$metric_id,$debug);
			if (defined($value) && $value){$total += $value;}
			$cpt++;
		    }
		    $result = $total / $cpt;
		} elsif ($ref->{'calcul_type'} =~ "SOM"){
		    while ($svc = $sth->fetchrow_hashref()){
			if (defined($svc->{'metric_id'})){$metric_id = $svc->{'metric_id'};}
			$value = get_value_in_database_metric_id($dbh,$dbh2,$metric_id,$debug);
			if ($value){$total += $value;}
			if ($debug){print "total = " . $total . "  value = ".$value."\n";} 
		    }
		    $result = $total;
		} elsif ($ref->{'calcul_type'} =~ "MIN"){
		    while ($svc = $sth->fetchrow_hashref()){
			if (defined($svc->{'metric_id'})){$metric_id = $svc->{'metric_id'};}
			$value = get_value_in_database_metric_id($dbh,$dbh2,$metric_id,$debug);
			if ($debug){print " min : " . $min . "  value = ".$value."\n";} 
			if ($value && $value <= $min){$min = $value;}
		    }
		    $result = $min;
		} elsif ($ref->{'calcul_type'} =~ "MAX"){
		    while ($svc = $sth->fetchrow_hashref()){
			if (defined($svc->{'metric_id'})){$metric_id = $svc->{'metric_id'};}
			$value = get_value_in_database_metric_id($dbh,$dbh2,$metric_id,$debug);
			if ($debug){print "max = " . $max . "  value = ".$value."\n";}
			if ($value && $value >= $max){$max = $value;}
		    }
		    $result = $max;
		}     
		return_value($result, $warning, $critical, $opt_i);
    }
}


sub print_usage () {
    print "Usage:\n";
    print " check_meta_service\n";
    print "   -i				Meta Service id\n";
    print "   -V (--version)    Plugin version\n";
    print "   -h (--help)       usage help\n";
}

sub print_help () {
    print "##############################################\n";
    print "#    Copyright (c) 2004-2008 Centreon        #\n";
    print "#    Bugs to http://trac.centreon.com/       #\n";
    print "##############################################\n";
    print_usage();
    print "\n";
}
