$solver = $ARGV[0];
$jobdir = $ARGV[1];
$MAXFILESIZE = 50000000;

$size = (-s "$ARGV[1]/job.received");
if($size > $MAXFILESIZE) {
    rename "$ARGV[1]/job.received", "$ARGV[1]/job.toobig";
    $reason = "Total file submission size $size bytes is above the NEOS Server limit.\n";
    print $reason;
    exit(-1);
}

unless (-s "$ENV{SERVER_VAR}/lib/solvers/$solver/restrictions") {
  exit(0);
}
$counterFile = "$ENV{SERVER_VAR}/lib/solvers/$solver/restrictions";

open(COUNT, "$counterFile");
chomp(@counters = <COUNT>);
close COUNT;
open(ADD, "$jobdir/job.address");
chomp($address = <ADD>);
close ADD;
open(WHEN, "$jobdir/job.start");
chomp($when = <WHEN>);
close WHEN;	   
if ($when =~ /(.+) (.+)/) {
    $curDate = $1;
    $curTime = $2;
} else { 
    print STDERR "$jobdir/job.start mangled\n";
}

#
# cycle through counters, reset if necessary, and then decrement
#

foreach (@counters) {
    if(!(m/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*$/)) 
    {
	if(m/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*(\S*)\s*$/)
	{
	    $_ .= " -1";
	} else {
	    &invalid;
	}
    }
  $whom     = $1;
  $type     = $2;
  $max      = $3;
  $left     = $4;
  $lastDate = $5;
  $lastTime = $6;
  
  $whom     =~ s/^\///;
  $whom     =~ s/\/$//;

  if ($whom eq "#max") {
    $whom = ".";
  }

  #
  # when $whom = any_one_user or any_one_domain
  #

  if ($whom =~ /#max_any_one_(user|domain)/) {
      $which = $1;
      $changed = 1;		#always a change
      if(open(ANY, "$ENV{SERVER_VAR}/lib/solvers/$solver/any_one_$which")) {
	  chomp(@any = <ANY>);
	  close ANY;
      }
      $found = 0;
      if ($which eq "domain") {
	  if($address =~ m/(.+)\@(.+)/) {
	      $address = $2;
	  }
      }
      foreach (@any) {
	  /(\S+) (\S+) (\S+) (\S+)/;
	  $theirAddress = $1;
	  $left         = $2;
	  $lastDate     = $3;
	  $lastTime     = $4;
	  $left = &reset($type, $left, $max, $lastDate, $lastTime, $curDate, $curTime);
	  if ($address eq $theirAddress) {
	      $found = 1;
	      if ($left <= 0) {
		  $fail = 1;
		  $reason .= "\"$address\" has reached the solver-imposed \n $which limit of $max jobs/$type.\n";
	      } else {
		  $left--;
	      }
	      $any_one{"$which"} .= "$address $left $curDate $curTime\n";
	  } else {
	      if ($left < $max) {
		  $any_one{"$which"} .= "$_\n";
	      }
	  }

      }
      unless ($found) {
	  $left--;
	  $any_one{"$which"} .= "$address $left $curDate $curTime\n";
      }
  } elsif ($address =~ /$whom/) {

    #
    # specific user or group of users specified by regular expression $whom
    #

    $left = &reset($type, $left, $max, $lastDate, $lastTime, $curDate, $curTime);
    if ($left <= 0) {
      $fail = 1;
      if ($whom eq ".") {
        $reason .= "Solver limit of $max jobs/$type has been reached.\n";
      } else {
        $reason .= "Addresses matching \"$whom\" are limited by $solver to $max jobs/$type.\n";
      } 
    } else {
      $left--;
      $changed = 1;
    }
    if(!(s/\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*(\S*)\s*/$whom $type $max $left $curDate $curTime/)) {
	print "counters.pl: Substitution failed\n";
    }
  } 
  $newCounters .= "$_\n";
}

#
# fail if any counters were at zero
#

if ($fail) {
  print "$reason\n";
  exit(-1);
}

#
# update counters on disk
#

if ($changed) {
  open(handle, ">$counterFile") or die "Failed to open $counterFile\n";
  print handle $newCounters;  
  close(handle);
  if ($any_one{"domain"}) { 
    open(handle, ">$ENV{SERVER_VAR}/lib/solvers/$solver/any_one_domain") or die "Failed to open any_one_domain for writing\n";
    print handle $any_one{"domain"};
    close(handle);
  }
  if ($any_one{"user"}) { 
    open(handle, ">$ENV{SERVER_VAR}/lib/solvers/$solver/any_one_user") or die "Failed to open any_one_user for writing\n";
    print handle $any_one{"user"};
    close(handle);
  }
}

#
# reset() resets the $left to $max when the dates/times allow
#

sub reset {
    local($type, $lastDate, $lastTime, $curDate, $curTime);
    local($lastYear, $lastMonth, $lastHour, $curYear, $curMonth, $curHour, $curMinute);
    $type     = $_[0];
    $left     = $_[1];
    $max      = $_[2];
    $lastDate = $_[3];
    $lastTime = $_[4];
    $curDate  = $_[5];
    $curTime  = $_[6];
    if ($type =~ /hour/i) {
	if ($lastDate eq $curDate) {
	    $lastTime =~ /(\d+):/;
	    $lastHour = $1;
	    $curTime  =~ /(\d+):/;
	    $curHour  = $1;
	    if ($lastHour ne $curHour) {
		$left = $max;
	    }
	} else {
	    $left = $max;
	}
    } elsif ($type =~ /minute/) { 
	if ($lastDate eq $curDate) {
	    $lastTime =~ /(\d+):(\d+)/;
	    $lastHour = $1;
	    $lastMinute = $2;
	    $curTime  =~ /(\d+):(\d+)/;
	    $curHour  = $1;
	    $curMinute = $2;
	    if($lastHour eq $curHour) { 
		if ($lastMinute ne $curMinute) {
		    $left = $max;
		}
	    } else {
		$left = $max;
	    }
	} else {
	    $left = $max;
	}
    } elsif ($type =~ /day/i) {
	if ($lastDate ne $curDate) {
	    $left = $max;
	}
    } elsif ($type =~ /month/i) {
	$lastDate =~ /(\d+)\/(\d+)\/(\d+)/;
	$lastMonth = $1;
	$lastYear  = $3;
	$curDate   =~ /(\d+)\/(\d+)\/(\d+)/;
	$curMonth  = $1;
	$curYear   = $3;
	if ($curYear ne $lastYear) {
	    $left = $max;
	} else {
	    if ($curMonth ne $lastMonth) {
		$left = $max;
	    }
	}
    } else {
	&invalid;
    }
    return $left;
}
    
sub invalid {

    if (-s "$ENV{SERVER_VAR}/lib/solvers/$solver/CONTACT") {
	open(CONTACT, "$ENV{SERVER_VAR}/lib/solvers/$solver/CONTACT");
	$address = <CONTACT>;
	close CONTACT;
	$address =~ s/\s*$//;
	$address =~ s/^\s*//;
	if(length($address) > 0) {
	    open(MAIL, "|sendmail -oi -t") or die "Could not access sendmail program\n";
	    print MAIL<<END;
To: $address
Subject: ERROR!! Restrictions file for $solver
The restrictions file for $solver is invalid.  Please
correct the problem and resubmit your ADDSOLVER form.
For more information on the format of the restriction file,
see the admin faq.
END
            close MAIL;
	}
	print "Invalid restriction file.\nMail has been sent to the solver administrator, if possible.\n";
    } else {
	print "Invalid restriction file.  Please contact us for correction.\n";
    }
    exit(-1);
}

