#!/usr/bin/perl
# Author: Dave Stern (dave@davestern.com)
# Version: 0.2


use lib '/usr/lib/nagios/plugins';
use utils qw(%ERRORS $TIMEOUT);

use strict;
use warnings;
use LWP::UserAgent;
use Getopt::Std;

sub main {

    my %options=();
    getopts("a:hu:p:P:s:v", \%options);

    if($options{'h'})
    {
        usage();
        exit $ERRORS{'UNKNOWN'};
    }

    if(! $options{'s'})
    {
        print qq|\nAt least one server name is required.\n|;
        exit $ERRORS{'UNKNOWN'};
    }


    my @servers = split(/,/, $options{'s'});

    my $port = $options{'P'} || 7474;
    my $path = $options{'a'} || '/db/manage/server/ha/available';

    if ($path !~ m@^/@)
    {
        $path = "/$path";
    }

    my $ua = LWP::UserAgent->new;
    $ua->timeout(10);

    my $totalServers = scalar(@servers);
    my %serverType = (
        'master' => 0,
        'slave'  => 0
    );

    my @errors;

    for my $server (@servers)
    {
        my $uri = qq|$server:$port$path|;

        if($server !~ /^http/i)
        {
            $uri = "http://$uri";
        }

        my $req = HTTP::Request->new(GET => $uri);
        my $res = $ua->request($req);

        if ($res->is_success) {
            $serverType{$res->content}++;
        }
        if ($res->is_error)
        {
            push(@errors, sprintf "[%d] %s", $res->code, $res->message);
        }
    }

    if($serverType{'master'} != 1)
    {
        push(@errors, "Master quantity is not exactly 1: $serverType{'master'} masters.");
    }

    if($serverType{'slave'} != ($totalServers - 1))
    {
        push(@errors, "Slave quantity is not exactly " . ($totalServers - 1) . ": $serverType{'slave'} slaves.");
    }

    if(@errors)
    {
        print "CRITICAL";
        if($options{'v'})
        {
            print ": " . join(" ", @errors);
        }
        exit $ERRORS{'CRITICAL'};
    }
    else
    {
        printf("%d master, %d slaves", $serverType{'master'}, $serverType{'slave'});
        exit $ERRORS{'OK'};
    }
}

sub usage {

    print qq|\nUsage: check_neo4j_cluster -s host1[,host2,etc] [-a path] \n[-P port] [-h this help message] [-v]\n|;

    print qq|\nOptions:

    -a Optional: Path to "available". Default: /db/manage/server/ha/available

    -h This help message

    -P Optional: Port. Default: 7474

    -s Required: Comma-separated list of servers to check

    -v verbose output\n\n|;

}

main();