#!/usr/bin/perl

use strict;

use lib '/var/lib/nocpulse/libexec';

use NOCpulse::Config;
use NOCpulse::Probe::PriorState;
use ProbeCatalog;

my @order = qw( lastStatus lastStatusMessage lastLatency nextRunTime
                lastExecTime lastExecutionTime lastNotification
                needRecovery lastStatusChange
                hostDown failures);


my %label = (
	     failures             => "Number of failures",
	     hostDown             => "Host is",
	     lastExecTime         => "Last run time",
	     lastExecutionTime    => "Last execution took",
	     lastLatency          => "Latency",
	     lastNotification     => "Last notification",
	     lastStatus           => "State",
	     lastStatusChange     => "Last state change",
	     lastStatusMessage    => "Last status message",
	     needRecovery         => "Needs recovery",
	     nextRunTime          => "Next run time",
	     );

my %decode = (
	      hostDown             => {1 => 'down', 0 => 'up'},
	      lastExecTime         => \&timestamp,
	      lastExecutionTime    => \&seconds,
	      lastLatency          => \&seconds,
	      lastStatusChange     => \&timestamp,
	      needRecovery         => {0 => 'no', 1 => 'yes'},
	      nextRunTime          => \&timestamp,
	      );

my %priorStateField = (
		       lastStatus        => "status",
		       lastStatusMessage => "status_message",
		       lastExecTime      => "last_run_time",
		       lastExecutionTime => "last_run_duration",
		       lastLatency       => "latency",
		       lastStatusChange  => "last_status_change",
		       nextRunTime       => "next_run_time"
		       );

# Set up the probe DB catalog
my $catalog = new ProbeCatalog();

# Print the status for all probes if none are given on commandline
my @probes = @ARGV ? @ARGV : sort {$a <=> $b} $catalog->all_probes();

my $priorState = NOCpulse::Probe::PriorState->instance();

use constant FORMAT => "%-10s %-27s %s\n";

print "\n";
foreach my $probeid (@probes) {

    print $catalog->describe($probeid)."\n";

    my $record ||= $priorState->load($probeid);

    my $key;
    foreach $key (@order) {
	if (exists($record->{$key})
	    || (exists($record->{schedule})
		&& exists($record->{schedule}->{$priorStateField{$key}}))
	    || $key eq "failures") {
	    my $label = exists($label{$key}) ? $label{$key} : "XXX $key";
	    my $value = $record->{$key};
	    $value ||= exists $record->{schedule} && $record->{schedule}->{$priorStateField{$key}};
	    if (!$value && $key eq "failures") {
		$value = $record->{attempts};
	    }
	    my $decoder = $decode{$key};

	    if (ref($decoder) =~ /CODE/) {

		$value = &$decoder($value);

	    } elsif (ref($decoder) =~ /HASH/) {

		$value = $decoder->{$value};
	    }
	    chomp($value);
	    printf FORMAT, $probeid, "${label}:", $value;
	}
    }

    # Dump probe-specific data
    if (ref($record) ne 'HASH') {
	while (my ($key, $value) = each %$record) {
	    next if ($key eq 'name' or $key eq 'readOnly');
	    if (!exists($label{$key})) {
		printf FORMAT, $probeid, "$key:", $value;
	    }
	}
    } else {
	foreach my $item_hash (@{$record->{items}}) {
	    my $item = NOCpulse::Probe::ItemStatus->new(%$item_hash);
	    while (my ($status, $time) = (each %{$item->status_notified_time})) {
		printf FORMAT, $probeid, "Last $status notification:",
		timestamp($time)." (".$item->name.")";
	    }
	}
      while (my ($key, $value) = each %{$record->{memory}}) {
          printf FORMAT, $probeid, "$key:", $value;
      }
    }
    print "\n";
}



sub timestamp {
    my $time = shift;
    my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);
    return sprintf("%02d/%02d/%4d %02d:%02d:%02d",
		   $mon+1, $mday, $year + 1900, $hour, $min, $sec);
}


sub seconds {
    return sprintf("%s seconds", shift);
}


__END__

=head1 NAME

status - Show status of NOCpulse probes

=head1 SYNOPSIS

    status [<probeid> [<probeid>...]]


=head1 DESCRIPTION

This script shows the status record for specified probeids, or all probes
if no probeids are specified on the commandline.

=head1 AUTHOR

  Nick Hansen <nhansen@redhat.com>
