#!/usr/bin/env perl

use strict;

require Office;
require SendZ;
require Err;

BEGIN {@main::Ids = (@main::Ids, '$Id: zbot.pl,v 1.10 2002/09/28 19:28:32 ingolia Exp $ ');}

my $headfile = '/afs/sipb.mit.edu/admin/office/office-heads';
my $peoplefile = '/afs/sipb.mit.edu/admin/office/members_and_prospectives';

my $office = new Office($headfile, $peoplefile);

if ($ARGV[0] eq 'test') {
    print "Test mode\n";

    foreach my $head ($office->heads()) {
	eval {
	  Idle::users_idle_times($head);
	    print "Fingered $head\n";
	} ;
	if ($@) {
	    print "Error fingering $head: $@\n";
	}
    }

    my %people = $office->people();
    print join(', ', keys(%people)) . "\n";

    foreach my $user ($office->sufficient_logins()) {
	print "$user\n";
    }

    exit 0;
} elsif (@ARGV) {
    die("Unknown command-line arguments: " . join(' ', @ARGV));
}

SendZ::zdebug('Starting zbot.pl on ' . `hostname` . " as $$");
map { SendZ::zdebug($_) } @main::Ids;



while (1) {
    eval {
	randomwait($office);
	do_clean($office);
    } ;

    if ($@) {
      Err::error('Error in main loop: ' . $@);
	sleep(60 * 60);
    }
}

Err::error('zbot exiting');
exit(0);

# Pick a random cleaning interval based on the office state and sleep
#   for that interval.
sub randomwait {
    my $office = shift or die('No office specified');

    my $delay = $office->waiting_time();
  SendZ::zdebug("Random delay of $delay seconds");
    sleep($delay);
}

# Check for sufficient logged-in users and announce a cleaning when 
#   there are enough users and there is no meeting.  Check for logged-in
#   people every 30 minutes.
sub do_clean {
    my $office = shift or die('No office specified');
    
    CLEAN: while (1) {
	eval {
	    if (!$office->in_meeting()) {
		my @logins = $office->sufficient_logins();
		if (@logins) {
		  SendZ::zdebug('Time for an office cleaning...');
		    announce_cleaning(@logins);
		    $office->now_cleaned();
		    last CLEAN;
		} else {
		  SendZ::zdebug('Insufficient people in office');
		}
	    } else {
	      SendZ::zdebug('Postponing for meeting');
	    }
	} ;

	if ($@) {
	  Err::error('Error trying cleaning: ' . $@);
	}

	sleep(30 * 60);	
    }
    
  SendZ::zdebug('Office cleaning announced');
}

# Announce a cleaning.  The list of users to be notified by personal 
#   zephyr is the argument list.
sub announce_cleaning {
  SendZ::announce(@_);
}
