#!/bin/bash
# vim: expandtab:ts=4:sw=4:syntax=perl

# read rc files if exist
unset PROFILEDOTD
[ -e /etc/thruk/thruk.env  ] && . /etc/thruk/thruk.env
[ -e ~/etc/thruk/thruk.env ] && . ~/etc/thruk/thruk.env
[ -e ~/.thruk              ] && . ~/.thruk
[ -e ~/.profile            ] && . ~/.profile

BASEDIR=$(dirname $0)/..

# git version
if [ -d $BASEDIR/.git -a -e $BASEDIR/lib/Thruk.pm ]; then
  export PERL5LIB="$BASEDIR/lib:$PERL5LIB";
  if [ "$OMD_ROOT" != "" -a "$THRUK_CONFIG" = "" ]; then export THRUK_CONFIG="$OMD_ROOT/etc/thruk"; fi
  if [ "$THRUK_CONFIG" = "" ]; then export THRUK_CONFIG="$BASEDIR/"; fi

# omd
elif [ "$OMD_ROOT" != "" ]; then
  export PERL5LIB=$OMD_ROOT/share/thruk/lib:$PERL5LIB
  if [ "$THRUK_CONFIG" = "" ]; then export THRUK_CONFIG="$OMD_ROOT/etc/thruk"; fi

# pkg installation
else
  export PERL5LIB=$PERL5LIB:@DATADIR@/lib:@THRUKLIBS@;
  if [ "$THRUK_CONFIG" = "" ]; then export THRUK_CONFIG='@SYSCONFDIR@'; fi
fi

eval 'exec perl -x $0 ${1+"$@"} ;'
    if 0;
# / this slash makes vscode syntax highlighting work
#! -*- perl -*-
#line 35

##############################################
use strict;
use warnings;
use Pod::Usage;
use Getopt::Long;
use Thruk::Utils::CLI;
use Thruk::Utils::Log qw/:all/;
use Encode qw/encode_utf8/;

binmode(STDOUT, ":encoding(UTF-8)");
binmode(STDERR, ":encoding(UTF-8)");

my $opt ={
    'help'      => 0,
    'lookback'  => 60,
    'backend'   => undef,
    'verbose'   => 0,
};
Getopt::Long::Configure('no_ignore_case');
Getopt::Long::Configure('bundling');
GetOptions (
    "h|help"         => \$opt->{'help'},
    "l|lookback=i"   => \$opt->{'lookback'},
    "b|backend=s"    => \$opt->{'backend'},
    "n|nocache"      => \$opt->{'nocache'},
    "f|foreground"   => \$opt->{'foreground'},
    "t|testmode"     => \$opt->{'testmode'},
    "v|verbose"      => sub { $opt->{'verbose'}++ },
) or pod2usage( { -verbose => 2, -message => 'error in options', -exit => 3 } );
pod2usage( { -verbose => 2,  -exit => 3 } ) if $opt->{'help'};

my $options = {};
$options->{backends} = [$opt->{'backend'}] if $opt->{'backend'};
my $cli     = Thruk::Utils::CLI->new($options);
my $c       = $cli->get_c();
Thruk::Action::AddDefaults::add_defaults($c);
my $start   = time() - $opt->{'lookback'};
my $db      = $cli->get_db();

my $logoptions = {
    filter => [
        time    => { '>=' => $start },
        time    => { '<=' => time() },
        type    => 'SERVICE DOWNTIME ALERT',
        message => { '~~' => ';STOPPED;' },
    ],
    sort => {'ASC' => 'time'},
};
$logoptions->{'nocache'} = 1 if $opt->{'nocache'};
my $logs = $db->get_logs(%{$logoptions});
_info(sprintf("fetched %i matching log entries", scalar @{$logs})) if $opt->{'verbose'};

# fetch global eventhandler status
my $status = $db->get_processinfo();

for my $l (@{$logs}) {
    _info(sprintf("scheduling eventhandler for %s - %s", $l->{'host_name'}, $l->{'service_description'}));
    if(!$status->{$l->{'peer_key'}}->{'enable_event_handlers'}) {
        _info("event_handler are globally disabled");
        next;
    }

    # expand eventhandler command
    my $service = $db->get_services(
                        filter  => [{ host_name => $l->{'host_name'}, description => $l->{'service_description'} }],
                        backend => [$l->{'peer_key'}],
    );
    if(!$service->[0]) {
        _error("cannot find matching service");
        next;
    }
    $service = $service->[0];
    if(!$service->{'event_handler'}) {
        _info("service has no event_handler");
        next;
    }
    if(!$service->{'event_handler_enabled'}) {
        _info("service has event_handler disabled");
        next;
    }

    my $host = $db->get_hosts(
                        filter  => [{ name => $l->{'host_name'} }],
                        backend => [$l->{'peer_key'}],
    );
    if(!$host->[0]) {
        _error("cannot find matching host");
        next;
    }
    $host = $host->[0];

    my $cmd = $db->expand_command(host => $host, service => $service, source => 'event_handler');
    if($cmd->{'note'}) {
        _error($cmd->{'note'});
        next;
    }

    my $cmd_line = $cmd->{'line_expanded'};
    if($opt->{'testmode'}) {
        _info(sprintf("(testmode) would run: %s\n", $cmd_line));
    }

    _info(sprintf("cmd: %s\n", $cmd_line));
    if($opt->{'foreground'}) {
        `$cmd_line`;
    } else {
        `$cmd_line >/dev/null 2>&1 &`;
    }
}

exit 0;

##############################################

=head1 NAME

trigger_eventhandler_at_downtime_end - Command line utility to trigger eventhandler when a downtime is over

=head1 SYNOPSIS

  Usage: trigger_eventhandler_at_downtime_end [-b backend] --lookback=<seconds>

=head1 DESCRIPTION

This script collects logs

=head1 OPTIONS

    -l|--lookback           amount of seconds to lookback into the logfile
    -b|--backend            specify backend if there are multiple connected
    -n|--nocache            bypass logcache (if enabled)
    -f|--foreground         do not run eventhandler in background
    -t|--testmode           do not actially run eventhandler command, just print it
    -v|--verbose            print additional debug information

=head1 EXAMPLE

    run eventhandler for all services which downtimes stopped in the last 60 seconds

trigger_eventhandler_at_downtime_end --lookback=60

=head1 AUTHOR

2019, Sven Nierlein, <sven@consol.de>

=cut
