#! /usr/bin/perl -w
#
# Centreon
#
# Source Copyright 2005-2023 Centreon
#
# Unauthorized reproduction, copy and distribution
# are not allowed.
#
# For more informations : contact@centreon.com
#

#
# Plugin init
#
use strict;
use warnings;
use DBI;
use Getopt::Long;
use Data::Dumper;
use vars qw($centreon_config);

require "/etc/centreon/conf.pm";

########################################
# GLOBAL VARIABLES COMMON TO ALL PLUGINS
########################################
my $PROGNAME = $0;
my $VERSION = "3.4.0";
my %ERRORS = ( "OK" => 0, "WARNING" => 1, "CRITICAL" => 2, "UNKNOWN" => 3, "PENDING" => 4);

###############
# HELP FUNCTION
###############
sub print_usage () {
    print "Usage:\n";    
    print "   -i (--id)      Id of the Business Activity\n";
    print "   -r (--retry)   Retry in second to connect to DB (default 10s)\n";
    print "   -v (--version) Plugin version\n";
    print "   -h (--help)    Displays this help\n";
}

###############
# HEADER FUNCTION
###############
sub print_help ()  {
    print "###########################################\n";
    print "#                                         #\n";
    print "#  Copyright (c) 2005-2023 Centreon       #\n";
    print "#  Bugs to http://www.centreon.com        #\n";
    print "#                                         #\n";
    print "###########################################\n";
    print_usage();
    print "\n";
}

############################
# GETTING PARAMETERS OPTIONS
############################
my %OPTION = ( "help" => undef, "version" => undef, "id" => undef, 'retry' => 10);

Getopt::Long::Configure('bundling');
GetOptions(
    "h|help" => \$OPTION{'help'},
    "v|version" => \$OPTION{'version'},
    "i|id=i" => \$OPTION{'id'},
    "r|retry=i" => $OPTION{'retry'}
);

if (defined($OPTION{'version'})) {
    print $PROGNAME." : ".$VERSION."\n";
    exit $ERRORS{'UNKNOWN'};
}

if (defined($OPTION{'help'})) {
    print_help();
    exit $ERRORS{'UNKNOWN'};
}

if (!defined($OPTION{'id'})) {
    print_help();
    exit $ERRORS{'UNKNOWN'};
}

#########################
##
## MAIN
##
#########################

my ($statefile_dir, $statefile);
$statefile_dir = "/var/lib/centreon/centplugins/";
$statefile = "centreon_bam_" . $OPTION{'id'};

my ($output, $perfdata, $status, $ref);

my $dsn = "DBI:mysql:database=$centreon_config->{centreon_db};host=$centreon_config->{db_host}";
my $dbh;

local $SIG{ALRM} = sub { 
    if ( -f $statefile_dir . '/' . $statefile ) {
        unless ($ref = do $statefile_dir . '/' . $statefile) {
            print "Cannot retreive cached data from last check\n";
            exit $ERRORS{'UNKNOWN'};
        }
        # Calculate output, perfdata & status
        my $output_bam = $ref->{'comment'};
        if (!length($output_bam)) {
            $output = sprintf("BA: %s - last level from cache = %d%%", $ref->{'name'}, $ref->{'current_level'});
            $perfdata = sprintf("BA_Level=%d%%;%d;%d;0;100", $ref->{'current_level'}, $ref->{'level_w'}, $ref->{'level_c'});
            $output_bam = sprintf("%s|%s", $output, $perfdata);
        }
        # Display result & exit with status
        print $output_bam . "\n";
        exit $ref->{'status'};
    } else {
        print "Cannot connect to database\n";
        exit $ERRORS{'UNKNOWN'};
    }
};
alarm($OPTION{'retry'});

# Try to connect during $OPTION{'retry'} seconds before to exit with last cached data
while (1) {
    $dbh = DBI->connect(
        $dsn,
        "$centreon_config->{db_user}",
        "$centreon_config->{db_passwd}",
        { RaiseError => 0, PrintError => 0 }
    );
    if (!$dbh) {
        sleep 1;
    } else {
        last;
    }
}
alarm(0);

my $sth = $dbh->prepare("SELECT `name`,`current_level`,`current_status`,`level_w`,`level_c`,`state_source`, `comment` FROM `mod_bam` WHERE `ba_id` = ?");
die "Error:" . $dbh->errstr . "\n" if (!$sth);
if (!$sth->execute($OPTION{'id'})) {
    die "Error:" . $sth->errstr . "\n";
}
$ref = $sth->fetchrow_hashref();

if (!defined($ref->{'name'})){
    print "Unknown Business Activity\n";
    exit $ERRORS{'UNKNOWN'};
}

# Calculate output, perfdata & status
my $output_bam = $ref->{'comment'};
if (!length($output_bam)) {
    $output = sprintf("BA: %s - current_level = %d%%", $ref->{'name'}, $ref->{'current_level'});
    $perfdata = sprintf("BA_Level=%d%%;%d;%d;0;100", $ref->{'current_level'}, $ref->{'level_w'}, $ref->{'level_c'});
    $output_bam = sprintf("%s|%s", $output, $perfdata);
}

$status = $ERRORS{'UNKNOWN'}; # set default value

if ($ref->{'state_source'} != 0) {
    # for calculation method different from Impact the status depends on the current_status value

    if ($ref->{'current_status'} == 0) {
        $status = $ERRORS{'OK'};
    } elsif ($ref->{'current_status'} == 1) {
        $status = $ERRORS{'WARNING'};
    } elsif ($ref->{'current_status'} == 2) {
        $status = $ERRORS{'CRITICAL'};
    } elsif ($ref->{'current_status'} == 3) {
        $status = $ERRORS{'UNKNOWN'};
    }
} elsif ($ref->{'current_level'} > $ref->{'level_w'}) {
    $status = $ERRORS{'OK'};
} elsif (($ref->{'current_level'} <= $ref->{'level_w'}) && ($ref->{'current_level'} > $ref->{'level_c'})) {
    $status = $ERRORS{'WARNING'};
} elsif (($ref->{'current_level'} <= $ref->{'level_c'})) {
    $status = $ERRORS{'CRITICAL'};
}

$ref->{'status'} = $status;

# Save data in the cache
if ( -d $statefile_dir ) {
    open FILE, '>', $statefile_dir . '/' . $statefile;
    print FILE Dumper($ref);
    close FILE;
}

# Display result & exit with status
print $output_bam . "\n";
exit $status;
