#!/usr/bin/perl -w
# Version:      0.3
# Date:         Feb 15, 2022
# Author:       ivan.stetka@live.com
# Summary:      This is a nagios plugin to check Pingdom webservers status over API.

use strict;
use Getopt::Long qw(:config no_ignore_case bundling);
use Time::Piece;
use POSIX qw(strftime);

my %STATES = (
    OK       => 0,
    WARNING  => 1,
    CRITICAL => 2,
    UNKNOWN  => 3
);

my @aData = ();
my @curl = ();
my $crit = 5;
my $countDown = 0;
my $countUp = 0;
my $countPaused = 0;
my @longtext = ();
my @valuesDown = ();
my @valuesNoDown = ();
my $pluralDown = "";
my $pluralUp = "";
my $pluralPaused = "";
my $token = "";
my $proxy = "";
my $server = "all";

GetOptions(
    'T|token:s'    => \$token,
    'P|proxy:s'    => \$proxy,
    'S|server:s'   => \$server

);

@curl = `curl -s -m 5 -x $proxy -u $token: https://api.pingdom.com/api/3.1/checks`;

if (!@curl) {
    print "CRITICAL: Pingdom API data not found, maybe problem with proxy or curl timeout.\n";
    exit($STATES{CRITICAL});
}

foreach my $curl (@curl) {
    if ($curl=~ /\{"checks":\[\{(.*)\}\],"counts"*/) {
        @aData = split('\}\,\{', $1);
    } else {
        print "CRITICAL: Expected Pingdom API data not found.\n\n";
        print "$_\n" for @curl;
        exit($STATES{CRITICAL});
    }
}

if ($server eq "all") {
    foreach my $aData (@aData) {
        if ($aData =~ /\"id\":(\d{4,10}),.*,\"name\":\"(.*)\",\"hostname\":\"(.*)\",\"resolution.*,\"lasttesttime\":(\d{9,10}),\".*,\"status\":\"(up|down|paused|unknown)\".*/) {
            count();
        } else {
            print "CRITICAL: Wrong format of some server data (maybe $2)\n.$aData \n";
            exit($STATES{CRITICAL});
        }
    }
} else {
    foreach my $aData (@aData) {
        if ($aData =~ /\"id\":(\d{4,10}),.*,\"name\":\"(.*)\",\"hostname\":\"($server)\",\"resolution.*,\"lasttesttime\":(\d{9,10}),\".*,\"status\":\"(up|down|paused|unknown)\".*/) {
            count();
        }
    }
    if (($countDown + $countUp + $countPaused) != 1) {
        print "CRITICAL: Webserver $server not found.\n\n";
        print "$_\n" for @aData;
        exit($STATES{CRITICAL});
    }
}

my $valueDown = join(", ",@valuesDown);
my $valueNoDown = join(", ",@valuesNoDown);
if ($countDown > 1) { $pluralDown = "s"; }
if ($countUp > 1) { $pluralUp = "s"; }
if ($countPaused > 1) { $pluralPaused = "s"; }

if ($countDown >= 1) {
    if ($server eq "all") {
        print "CRITICAL: $countDown webserver$pluralDown: $valueDown.\n";
    } else {
        print "CRITICAL: $valueDown.\n";
    }
}

if ($countDown == 0) { 
    if ($server eq "all") {
        if ($countPaused == 0) {
        print "OK: Status on $countUp webserver$pluralUp is UP.\n";
        } else {
        print "OK: Status on $countUp webserver$pluralUp is Up and $countPaused webserver$pluralPaused is Paused.\n";
        }
    } else { print "OK: $valueNoDown.\n";
    }
}

print "\n";
print "$_\n" for @longtext;
print "\n";
print"|DownCount=$countDown;;1";

if ($countDown >= 1) {
    exit($STATES{CRITICAL});
    } else {
    exit($STATES{OK});
}
      
# # # SUBROUTINES # # #

# COUNT 
sub count {
    if ($5 eq "down" || $5 eq "unknown") {
            $countDown++;
            push @valuesDown, "$3 is $5";
        } elsif ($5 eq "up") {
            $countUp++;
            push @valuesNoDown, "$3 is $5";
        } elsif ($5 eq "paused") {
            $countPaused++;
            push @valuesNoDown, "$3 is $5";
        } else {
            print "CRITICAL: Unknown status of server $3.\n";
            exit($STATES{CRITICAL});
            print "$5 \n";
        }
        my $testTime = strftime("%Y-%m-%d %H:%M:%S", localtime($4));
        push @longtext, "ID: $1, LastTestTime: $testTime, Hostname: $3 is $5.";
}
