package APKPM::Poll;

use base qw(Gearman::Driver::Worker);
use Moose;
use Time::HiRes qw(time);
use Data::Dump qw(dump);
use Redis;
use DateTime;
use DateTime::Format::Pg;

with 'APKPM::Gearman::Client';
with 'APKPM::Gearman';

sub prefix { 'poll_' }

sub by_prefix : Job : MinProcesses(1) : MaxProcesses(1) : Encode(e_json) {
	my ( $self, $job, $workload ) = @_;

	my $start = DateTime->now();

	my $entries = $self->do( 'LDAP_search' => "(&(cn=$workload*)(dhcpStatements=*))" );

	my $ip_username;
	foreach my $entry ( @$entries ) {
		$ip_username->{ $entry->{cn} } = $1 if $entry->{dhcpStatements} =~ m/fixed-address\s+(\S+)/;
	}

	my $redis = Redis->new;
	$redis->del( $_ ) foreach $redis->keys('poll.*');

	my $taskset = $self->gc->new_task_set;
	my $results;
	while (my ($username,$ip) = each %$ip_username) {
		$taskset->add_task('poll_ip_username', "$ip $username", {
			on_complete => sub { push @$results, ${$_[0]} }
		});
		$redis->sadd('poll.queued' => $ip);
	}

	warn "# wait";
	$taskset->wait;

	my $finish = DateTime->now();

	my $poll;
	foreach my $k ( $redis->keys('poll.*') ) {
		my $n = $k;
		$n =~ s/^poll\.//;
		$n =~ s/\./_/g;
		$poll->{$n} = $redis->scard($k);
	}
	$poll->{start}  = DateTime::Format::Pg->format_datetime($start);
	$poll->{finish} = DateTime::Format::Pg->format_datetime($finish);

	$poll->{_table} = 'poll';

	warn dump $poll;
	$self->do_background_json('Store_insert_table', $poll);

	return { ldap => $ip_username, results => $results, duration => $finish - $start, poll => $poll };
}

sub ip_username : Job : MinProcesses(1) : MaxProcesses(25) : Decode(d_array) : Encode(e_json) {
	my ( $self, $job, $workload ) = @_;

	my ( $ip, $username ) = @$workload;

	return { error => "invalid workload", expected => "ip username" } unless $ip && $username;
	my $ping = $self->do('ping', $ip);

	my $redis = Redis->new;

	if ( exists $ping->{error} ) {
warn "XXX error: $ip";
		$redis->sadd( 'poll.ping.error' => $ip );
		return $ping;
	} else {
		$redis->sadd( 'poll.ping.ok' => $ip );
	}

	$ping->{username} = $username;
	$self->do_background_json( 'Store_ping', $ping );

	$self->do_background( 'Davolink_info', "$ip $username adsl" );

	return $ping;
}

1;
