use warnings;
use strict;
use Test::More;
use URI::Escape;

eval "use Test::Cmd";
plan skip_all => 'Test::Cmd required' if $@;
plan skip_all => 'backends required' if(!-s 'thruk_local.conf' and !defined $ENV{'PLACK_TEST_EXTERNALSERVER_URI'});
`ps -fu root | grep cron >/dev/null 2>&1`;
plan skip_all => 'crond required' if $? != 0;

BEGIN {
    use lib('t');
    require TestUtils;
    import TestUtils;
}

my $BIN = defined $ENV{'THRUK_BIN'} ? $ENV{'THRUK_BIN'} : './script/thruk';
$BIN    = $BIN.' --local' unless defined $ENV{'PLACK_TEST_EXTERNALSERVER_URI'};
$BIN    = $BIN.' --remote-url="'.$ENV{'PLACK_TEST_EXTERNALSERVER_URI'}.'"' if defined $ENV{'PLACK_TEST_EXTERNALSERVER_URI'};

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

# get test host
my $host = TestUtils::get_test_host_cli($BIN);

my $rand    = int(rand(1000000));
my $comment = 'test downtime '.$rand;
my $test_downtime = [{
    'type'          => 6,
    'target'        => 'host',
    'host'          => $host,
    'comment'       => $comment,
    'send_type_1'   => 'cust',
    'send_day_1'    => 1,
    'week_day_1'    => '0',
    'send_hour_1'   => '0',
    'send_minute_1' => '0',
    'send_cust_1'   => '* * * * *',
    'duration'      => 2,
    'fixed'         => 1,
    'flex_range'    => 720,
    'childoptions'  => 0,
    'nr'            => 9999,
    'verbose'       => 1,
}];

for my $downtime (@{$test_downtime}) {
    # create downtime
    my $args = [];
    for my $key (keys %{$downtime}) {
        push @{$args}, $key.'='.$downtime->{$key};
    }
    TestUtils::test_command({
        cmd  => $BIN.' "extinfo.cgi?recurring=save&'.join('&', @{$args}).'"',
        like => ['/^OK - recurring downtime saved$/'],
    });

    my $host      = $downtime->{'host'};
    my $user      = defined $ENV{THRUK_USER} ? ' -u '.$ENV{THRUK_USER} : '';
    my $cronentry = `crontab -l $user | grep downtimetask | grep '9999'`;
    chomp($cronentry);
    like($cronentry, '/downtimetask /', "got cron entry: ".$cronentry) or BAIL_OUT("$0: got no cron entry");

    my($logfile) = ($cronentry =~ m/>>(.*?cron\.log)/mx);
    like($logfile, '/cron\.log$/', "got cron log: ".$logfile);
    `>$logfile`;

    # wait 150 seconds for a downtime
    my $now   = time();
    my $found = 0;
    while($now > time() - 150) {
        my $test = { cmd  => $BIN.' "extinfo.cgi?type=1&host='.$host.'"'};
        TestUtils::test_command($test);
        if($test->{'stdout'} =~ m/\(cron\)<\/td>\s+<td[^>]*>$comment/gs) {
            ok(1, "downtime occured after ".(time()-$now)." seconds");
            $found = 1;
            last;
        }
    }
    if(!$found) {
        fail("downtime did not occur in time");
        for my $cmd ("cat $logfile",
                     "crontab -l $user",
                     "ps -efl",
                     "$BIN 'extinfo.cgi?type=6'",
                     "$BIN 'showlog.cgi?pattern=EXTERNAL+COMMAND&start=yesterday&end=now'",
                    ) {
            diag("cmd: $cmd");
            diag(`$cmd`);
        }
    }
}

################################################################################
# run downtime from cli
TestUtils::test_command({
    cmd  => $BIN.' downtimetask 9999',
    like => ['/scheduled downtime/'],
});

# run downtime in test mode
TestUtils::test_command({
    cmd     => $BIN.' downtimetask 9999 -t',
    like    => ['/scheduled downtime/'],
    errlike => ['/TESTMODE:/'],
});

################################################################################
# remove downtime
TestUtils::test_command({
    cmd  => $BIN.' "extinfo.cgi?type=6&recurring=remove&nr=9999"',
    like => ['/^OK - recurring downtime removed$/'],
});

done_testing();
