#!/usr/bin/perl -w

use strict;
use warnings;

use Date::Parse qw(str2time);
use Getopt::Long qw(GetOptions);
use LWP::UserAgent ();
use Number::Format ();
use noris::NetSaint;

GetOptions
  'add-header=s'      => \my %Header,
  'days-critical=f'   => \my $DaysCritical,
  'days-warning=f'    => \my $DaysWarning,
  'octets-critical=i' => \my $OctetsCritical,
  'octets-warning=i'  => \my $OctetsWarning,
  'url=s'             => \my $Url,
  'help|?'            =>
  sub { exec perldoc => -F => $0 or die "exec('perldoc -F $0'): $!\n" },
  or exit noris::NetSaint::Status->new('Unknown');

die "Es muss eine --url angegeben werden.\n" unless defined $Url;

my $NetSaint      = noris::NetSaint->new;
my $number_format =
  Number::Format->new( -decimal_point => ',', -thousands_sep => '.' );

unless (
    ( my $response = LWP::UserAgent->new->get( $Url, %Header ) )->is_success )
{
    $NetSaint->update(
        Unknown => qq(Konnte <$Url> nicht laden: ) . $response->status_line );
}
elsif (
    !defined( my $last_modified_string = $response->header('Last-Modified') ) )
{
    $NetSaint->update( Unknown =>
"Beim Aufruf von <$Url> wurde kein Last-Modified:-Header mitgeliefert.\n"
    );
}
elsif ( !defined( my $last_modified_time = str2time($last_modified_string) ) ) {
    $NetSaint->update( Unknown =>
"Konnte Inhalt des Last-Modified:-Headers nicht parsen: $last_modified_string"
    );
}
else {
    my $age_in_days = ( $^T - $last_modified_time ) / 86400;
    $NetSaint->update(
          $age_in_days > $DaysCritical ? 'Critical'
        : $age_in_days > $DaysWarning  ? 'Warning'
        : 'OK',
        qq(<$Url> wurde zuletzt vor )
          . $number_format->format_number( $age_in_days, 1 )
          . ' Tagen aktualisiert.'
    );

    if ( $NetSaint->status eq 'OK' ) {
        unless ( my ( $mails, $octets ) =
            $response->content =~ /^\(Summe\).*\t(\d+)\t(\d+)\n\z/m )
        {
            $NetSaint->update(
                Warning => qq(Kann Summenzeile aus <$Url> nicht parsen.\n) );
        }
        else {
            $NetSaint->update(
                defined $OctetsCritical
                  && $octets > $OctetsCritical
                ? 'Critical'
                : defined $OctetsWarning
                  && $octets > $OctetsWarning ? 'Warning' : 'OK',
                'Die Postfcher belegen '
                  . $number_format->format_number( $octets / 2**30, 2 ) . ' GB.'
            );
        }
    }
}

__END__

=head1 NAME

check_postfachliste - Nagios-Monitoring-Plugin, vgl. RT#267438

=head1 BESCHREIBUNG

Dieses Nagios-Monitoring-Plugin berwacht die Aktualitt einer von
C<acct.postfaecher> generierten Liste, die es dazu via HTTP(S) abruft, sowie die
Gesamtgre des durch diese Postfcher belegten Festplattenplatzes laut dieser
Liste.

=head1 NOTWENDIGE ARGUMENTE

=head2 url=s

URL, unter der sich die zu untersuchende Postfach-Liste findet

=head1 OPTIONEN

=head2 add-header=s %

zustzliche Header, die beim HTTP(S)-GET-Request mitgeschickt werden sollen
(z. B. fr C<Authorization>)

=head2 days-critical=f

Maximalalter der L<Datei|/file=s> in Tagen, bei dessen berschreiten ggf. ein
kritischer Status ausgegeben werden soll

=head2 days-warning=f

Maximalalter der L<Datei|/file=s> in Tagen, bei dessen berschreiten ggf. ein
Warn-Status ausgegeben werden soll

=head2 octets-critical=i

maximaler Plattenplatz in Bytes, der von allen Mailboxen zusammen belegt werden
darf; bei berschreiten wird eine Warnung ausgegeben

=head2 octets-warning=i

maximaler Plattenplatz in Bytes, der von allen Mailboxen zusammen belegt werden
darf; bei berschreiten wird ein kritischer Status ausgegeben

=head2 help|?

um (nur) diese Dokumentation anzeigen zu lassen

=head1 AUTOR

 Martin H. Sluka <fany@noris.net>
 im Rahmen von RT#267438

=cut

