#!/usr/bin/perl -w

our ($user, $pass);
do "$ENV{HOME}/.fclpass";
my $host = "mail.messagingengine.com";
my $port = 143;

use strict;
use IO::Socket;

my $alarm_triggered = 0;

$SIG{CHLD} = 'IGNORE';
$SIG{ALRM} = sub { $alarm_triggered = 1; };

run_offlineimap();

while (1) {
	my $sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port);
	if (!$sock) {
		system "xmessage", "-geometry", "-0-0", "fastchecklite: can't connect - dying";
		die "can't connect";
	}
	print $sock ". login $user $pass\n"; sleep 1;
	print ". login $user ********\n";
	print $sock ". select inbox\n"; sleep 1;
	print ". select inbox\n";
	print $sock ". idle\n"; sleep 1;
	print ". idle\n";
	my $idling = 0;
	my $fetching = 0;
	my @msg_ids;
	my $n_msgs;
	my $wait_for_alarm = 0;
	while (1) {
		eval {
			local $SIG{ALRM} = sub { $alarm_triggered = 1; die "alarm\n"; };
			if (!$alarm_triggered) {
				$_ = <$sock>;
			}
		};
		if ($alarm_triggered) {
			run_offlineimap();
			$wait_for_alarm = 0;
			$alarm_triggered = 0;
			next;
		}
		if (!defined $_) {
			last;
		}
		print "### $_";
		if (/\+ idling/) {
			$idling = 1;
			print "# IDLING!\n";
		}
		if (/^\* (\d+) EXISTS/) {
			if (defined $n_msgs && $1 > $n_msgs) {
				print "# A NEW MESSAGE!\n";
				for ($n_msgs+1 .. $1) {
					push @msg_ids, $_;
				}
			}
			$n_msgs = $1;
		}
		if (!$fetching && @msg_ids) {
			my $id = shift @msg_ids;
			print $sock <<End;
DONE
. fetch $id envelope
End
			$fetching = 2;
		}
		if ($fetching) {
			if (/^\. OK/) {
				$fetching --;
				if ($fetching == 0) {
					print "\n";
					if (!$wait_for_alarm) {
						print "scheduling offlineimap alarm for 3 seconds...\n";
						alarm(3);
						$wait_for_alarm = 1;
					}

					print $sock ". idle\n"; sleep 1;
					$idling = 0;
				}
			}
			elsif ($fetching == 1) { print; s/.*?"/"/; bg("xmessage", $_); }
		}
	}
	print "# DISCONNECTED\n";
}

sub bg {
	my $childpid = fork();
	if (! defined $childpid) {
		die "can't fork";
	}
	if ($childpid == 0) {
		exec @_;
		die "exec failed";
	}
	return $childpid;
}

sub run_offlineimap {
#	print "NOT running offlineimap...\n";
#	return;
	chomp(my $dt = `dt`);
	print "$dt: running offlineimap...\n";
	if (-e "$ENV{HOME}/deadletter") {
		bg "xmessage", "-geometry", "-0-0", "fastchecklite: warning, ~/deadletter exists";
	}
	system("offlineimap");
}
