#! /usr/bin/perl
#use BER;
use Data::Dumper;
use DBI;
use POSIX;
use Time::HiRes;
use lib '../include';
use nms;
use strict;
use warnings;

# Tweak timeouit og sjekk med :support||:net hva passord vil bli
my $location = 'skipet';

my $dbh = nms::db_connect();
$dbh->{AutoCommit} = 0;

my $qswitch = $dbh->prepare(<<"EOF")
SELECT 
  *
FROM
  switches
  NATURAL LEFT JOIN switchtypes
WHERE
  (locked='f' OR now() - last_updated > '15 minutes'::interval)
LIMIT 1
FOR UPDATE OF switches
EOF
	or die "Couldn't prepare qswitch";
my $qlock = $dbh->prepare("UPDATE switches SET locked='t', last_updated=now() WHERE switch=?")
	or die "Couldn't prepare qlock";
my $qunlock = $dbh->prepare("UPDATE switches SET locked='f', last_updated=now() WHERE switch=?")
	or die "Couldn't prepare qunlock";
my $qpoll = $dbh->prepare("INSERT INTO temppoll (time, switch, temp) VALUES (timeofday()::timestamp,?::text::int,?::text::float)")
	or die "Couldn't prepare qpoll";

while (1) {
	# Find a switch to grab
	$qswitch->execute()
		or die "Couldn't get switch";
	my $switch = $qswitch->fetchrow_hashref();

	if (!defined($switch)) {
		$dbh->commit;
		mylog("No available switches in pool, sleeping.");
		sleep 60;
		next;
	}

	$qlock->execute($switch->{'switch'})
		or die "Couldn't lock switch";
	$dbh->commit;

	if ($switch->{'locked'}) {
		mylog("WARNING: Lock timed out on $switch->{'ip'}, breaking lock");
	}

	my $msg;
	if (defined($switch->{'overdue'})) {
		$msg = sprintf "Polling temp on %s (%s), %s overdue.",
			$switch->{'ip'}, $switch->{'sysname'}, $switch->{'overdue'};
	} else {
		$msg = sprintf "Polling temp on %s (%s), never polled before.",
			$switch->{'ip'}, $switch->{'sysname'};
	}
	mylog($msg);

	my $ip = $switch->{'ip'};
	my $start = [Time::HiRes::gettimeofday];
	eval {
		my $conn = nms::switch_connect($ip);
		if (!defined($conn)) {
			print "Could not connect to switch ".$switch->{'switch'}."\n";
		}
		my @data = switch_exec('sys monitor status', $conn);
		my @fields = split(/\s+/, $data[2]);
		# The temp fields are 6, 7, 8
		my $avgtemp = ($fields[6] + $fields[7] + $fields[8]) / 3;
		print $avgtemp." avgtemp\n";
		$qpoll->execute($switch->{'switch'},
		                $avgtemp) or die "Could not exec qpoll";
	};
	my $elapsed = Time::HiRes::tv_interval($start);
	$msg = sprintf "Polled $switch->{'ip'} in %5.3f seconds.", $elapsed;
	mylog($msg);

	$qunlock->execute($switch->{'switch'})
		or die "Couldn't unlock switch";
	sleep 1;
	$dbh->commit;
}

sub switch_exec {
	my ($cmd, $conn) = @_;

	# Send the command and get data from switch
	my @data = $conn->cmd($cmd);
	my @lines = ();
	foreach my $line (@data) {
		# Remove escape-7 sequence
		$line =~ s/\x1b\x37//g;
		push (@lines, $line);
		}

	return @lines;
}

sub mylog {
	my $msg = shift;
	my $time = POSIX::ctime(time);
	$time =~ s/\n.*$//;
	printf STDERR "[%s] %s\n", $time, $msg;
}
