use File::Copy;
require "flush.pl";

$SERVER_HOME   = $ENV{SERVER_HOME};
$SOLVERS       = $ENV{SERVER_SOLVERS};
$ADMIN_SOLVERS = $ENV{SERVER_ADMIN_SOLVERS};
$DEFAULTS      = "$ADMIN_SOLVERS/ADMIN:ADDSOLVER/defaults";
$still_need    = "";
$sign          = "$ENV{SERVER_SIGNATURE}\n($ENV{SERVER_COMMENTS})";

print "Running data check:\n\n"; &flush(STDOUT);

#
# Software Type 
#

if (system("$^X $ADMIN_SOLVERS/ADMIN:ADDSOLVER/verify_type.pl > verify_type.out")) {
  chop($error = `cat verify_type.out`);
  &fail("Solver Type", "$error");
} else {
  chop($TYPE = `cat TYPE`);
  $TYPE = "\U$TYPE";
  printf("%25s  %s\n", "Solver Type", "OK"); 
  &flush(STDOUT);
}

#
# Solver Identifer 
#

if (system("$^X $ADMIN_SOLVERS/ADMIN:ADDSOLVER/verify_token.pl >verify_token.out")) {
  chop($TOKEN = `cat verify_token.out`);
  &fail("Solver Identifier", "$TOKEN");
} else {
  chop($TOKEN = `cat TOKEN`);
  $TOKEN = "\U$TOKEN";
  $DIR = "$SOLVERS/$TYPE:$TOKEN";
  printf("%25s  %s\n", "Solver Identifier", "OK"); 
  &flush(STDOUT);
}
 
#
# Software Name
#

if (system("$^X $ADMIN_SOLVERS/ADMIN:ADDSOLVER/verify_title.pl >verify_title.out")) {
  chop($TITLE = `cat verify_title.out`);
  &fail("Solver Name", "$TITLE");
} else {
  $TITLE = `cat TITLE`;
  printf("%25s  %s\n", "Solver Name", "OK"); 
  &flush(STDOUT);
}

$SOLVER = "\U$TITLE";
$SOLVER =~ s/\s//g;

#
# Password
#

if (system("$^X $ADMIN_SOLVERS/ADMIN:ADDSOLVER/verify_password.pl >verify_password.out")) {
  chop($PASSWORD = `cat verify_password.out`);
  &fail("Password", "$PASSWORD");
} else {
  $PASSWORD = `cat PASSWORD`;
  $COMMAND = "$^X $ADMIN_SOLVERS/ADMIN:ADDSOLVER/check_password.pl $TOKEN $PASSWORD";
  unless (system("$COMMAND")) {
    printf("%25s  %s\n", "Solver Password", "OK"); 
    &flush(STDOUT);
  } else {
    $PASSWORD = "incorrect password for \"$TOKEN.\"";
    &fail("$PASSWORD");
  }
}

#
# Contact person
#

if (system("$^X $ADMIN_SOLVERS/ADMIN:ADDSOLVER/verify_contact.pl >verify_contact.out")) {
  chop($error = `cat verify_contact.out`); 
  &fail("Contact Person", "$error");
} else {
  $CONTACT = `cat CONTACT`;
  printf("%25s  %s\n", "Contact Person", "OK"); 
}


#
# List of workstations
#

if (system("$^X $ADMIN_SOLVERS/ADMIN:ADDSOLVER/verify_workstations.pl >verify_workstations.out")) {
  chomp($STATIONS = `cat verify_workstations.out`);
  &fail("Workstations", "$STATIONS");
} else {
  $STATIONS = `cat STATIONS`;
  printf("%25s  %s\n", "Workstations", "OK"); 
  &flush(STDOUT);
}

#
# Usage restrictions
#

if (-f "restrictions") {
  if (system("$^X $ADMIN_SOLVERS/ADMIN:ADDSOLVER/verify_restrictions.pl > verify.out")) {
    chomp($restrict = `cat verify.out`);
    &fail("Usage Restrictions", "$restrict");
  } else {
    printf("%25s  %s\n", "Usage Restrictions", "OK"); 
    &flush(STDOUT);
  }
}

#
# Token configuration file
#

unless (-s "config") {
  printf("%25s  %s\n", "Token Configuration", "MISSING"); 
  $still_need .= "-Token Configuration\n";
} else {
  if (system("$^X $ADMIN_SOLVERS/ADMIN:ADDSOLVER/verify_config.pl > verify.out")) {
    chop($config = `cat verify.out`);
    &fail("in token configuration file\n", "$config");
  } else {
    printf("%25s  %s\n", "Token Configuration", "OK"); 
    $config = `cat config`;
  }
}

if ($ENV{SERVER_EMAIL_READY}) {

  #
  # e-mail help file
  #

  if (-s "help") {
    chop($help = `cat help`);
    printf("%25s  %s\n", "E-mail Help", "OK"); 
    &flush(STDOUT);
  } else {
    printf("%25s  %s\n", "E-mail Help", "MISSING"); 
    copy("$DEFAULTS/email-help","help") or system("cp $DEFAULTS/email-help ./help");
    $still_need .= "-E-mail Help\n";
  }
}

#
# Submission tool help file
#

if (-s "socket-help") {
  chop($socket = `cat socket-help`);
  printf("%25s  %s\n", "Submission Tool Help", "OK"); 
  &flush(STDOUT);
} else {
  printf("%25s  %s\n", "Submission Tool Help", "MISSING"); 
  copy("$DEFAULTS/socket-help","socket-help") or system("cp $DEFAULTS/socket-help .");
  $still_need .= "-Submission Tool Help\n";
}

if ($ENV{SERVER_WWW_READY}) {

  #
  # Web Submission
  #

  unless (-s "explain") {
    $still_need .= "-Web Help\n";
    printf("%25s  %s\n", "WWW Help", "MISSING"); 
  } else {
    printf("%25s  %s\n", "WWW Help", "OK"); 
  }

  #
  # Samples
  #

  unless (-s "trial_config") {
    $still_need .= "-WWW Samples\n";
    printf("%25s  %s\n", "WWW Samples", "MISSING"); 
  } else {
    printf("%25s  %s\n", "WWW Samples", "OK"); 
  }

  #
  # HTML Abstract
  #

  unless (-s "abstract") {
    $still_need .= "-WWW Abstract\n";
    printf("%25s  %s\n", "WWW Abstract", "MISSING"); 
  } else {
    printf("%25s  %s\n", "WWW Abstract", "OK"); 
  }

  #
  # "Background URL" 
  #

  unless (-s "about.url") {
    $ABOUT_URL = "default";
    printf("%25s  %s\n", "WWW About URL", "MISSING"); 
    $still_need .= "-WWW About URL\n";
  } else {
    printf("%25s  %s\n", "WWW About URL", "OK"); 
    chop($ABOUT_URL = `cat about.url`);  
  }


  if($ENV{SERVER_SOLVER_GROUPS}) {

    if(-f "GROUP") {
      opendir CURDIR, "." or die "Could not open the current directory.\n";
      @allfiles = grep /\.in$/, readdir CURDIR;
      closedir CURDIR;
      if(scalar(@allfiles)<1) {
        &fail("Solver group/Features","If you list a group for the solver, you must also \n       select a feature to distinguish the solver from other \n       members of the group.  You can correct this problem \n       either by leaving the Solver Group field blank, by \n       selecting from the list of solver features, or by \n       entering a different feature for Other features.\n");
      }
    }
    open(IN, "$ENV{SERVER_VAR}/lib/feature_tree") or print "Could not open features tree.\n" and die;
    @inputs = <IN>;
    close IN;
    @accepts = ();
    foreach $input (@inputs) {
      $input =~ /=(.*)\s$/;
      $input = $1;
      if (-f "$input.in") {
        open(IN, "$input.in");
        $accepts = <IN>;
        close IN;
        $accepts =~ s/\s//g;
        if($accepts =~ /\S+/ and $accepts !~ /^no$/i ) {
          @accepts = (@accepts, $input);
        }
      }
    }

    open(ACCEPTS, ">ACCEPTS");
    foreach $accepts (@accepts) {
      print ACCEPTS "$accepts<ACCEPTS>";
    }
    close ACCEPTS;
  }
}

print "\nUpdating solver library...\n"; &flush(STDOUT);

#
# Copy files into <SOLVERS> and update "solver_list" 
#

if ($still_need) {
  $still_need = "\nYou still need to provide the following information though:\n\n$still_need"; 
}

if (-e "$DIR") {
  $UPDATE = 1;
} else {
  system("mkdir $SOLVERS") unless (-d "$SOLVERS");
  system("mkdir $DIR");
}

#
# Copy files into <SOLVERS>/<solver>
#

$count = 0;
if (-f "$DIR/STATIONS") {
  chop(@oldStations = `cat $DIR/STATIONS`);
  chop($newStations = `cat STATIONS`);
  foreach $oldStation (@oldStations) {
    $oldStation =~ s/\s+\d+\s*$//;
    unless ($newStations =~ /$oldStation/) {
      open(HANDLE, ">$ENV{SERVER_TMP}/$$");
      print HANDLE "$oldStation:$TYPE:$TOKEN\n";
      close(HANDLE);
      $tag = $$ - $count;
      system("mv $ENV{SERVER_TMP}/$$ $ENV{SERVER_VAR}/spool/PORTS/port_delete.$tag");
      $count++;
    } 
  } 
  system("touch $ENV{SERVER_VAR}/spool/PORTS/UPDATE");
} 
system("/bin/rm -f $DIR/*");
copy("CONTACT","$DIR/CONTACT") or system("cp CONTACT $DIR");
copy("TITLE", "$DIR/TITLE") or system("cp TITLE $DIR");
copy("PASSWORD","$DIR/PASSWORD") or system("cp PASSWORD $DIR");
copy("STATIONS","$DIR/STATIONS") or system("cp STATIONS $DIR");
copy("socket-help","$DIR/submission-tool-help") or system("cp socket-help $DIR/submission-tool-help");
(copy("config","$DIR/config") or system("cp config $DIR")) if (-f "config");
(copy("help","$DIR/email-help") or system("cp help $DIR/email-help")) if (-f "help");
(copy("explain","$DIR/web-help") or system("cp explain $DIR/web-help")) if (-f "explain");
(copy("trial_config","$DIR/trial_config") or system("cp trial_config $DIR")) if (-f "trial_config");
(copy("abstract","$DIR/abstract") or system("cp abstract $DIR")) if (-f "abstract");
(copy("about.url","$DIR/about.url") or system("cp about.url $DIR")) if (-f "about.url");
(copy("restrictions","$DIR/restrictions") or system("cp restrictions $DIR")) if (-f "restrictions");
(copy("GROUP","$DIR/GROUP") or system("cp GROUP $DIR")) if(-f "GROUP");
(copy("ACCEPTS","$DIR/ACCEPTS") or system("cp ACCEPTS $DIR")) if (-f "ACCEPTS");
if(open(IN, "OTHER.in")) {
  chomp($others = <IN>);
  close IN;
  $others =~ s/\s//g;
  if(!($others eq "yes")) {
    copy("OTHER.in","$DIR/OTHER_FEATURES") or system("cp OTHER.in $DIR");
  }
}
chomp($TITLE);
$LIST = `cat $ENV{SERVER_VAR}/lib/solver_list`;
if ($LIST =~ /.*=$TYPE:$TOKEN\n/) {
    $LIST =~ s/(.*)=$TYPE:$TOKEN\n/$TITLE=$TYPE:$TOKEN\n/;
    open(HANDLE, ">$ENV{SERVER_TMP}/$$");
    print HANDLE $LIST;
    close(HANDLE);
} else {
  @LIST = ("$TITLE=$TYPE:$TOKEN\n",`cat $ENV{SERVER_VAR}/lib/solver_list`);
  @LIST = sort @LIST;
  open(HANDLE, ">$ENV{SERVER_TMP}/$$");
  print HANDLE @LIST;
  close(HANDLE);
}
rename("$ENV{SERVER_TMP}/$$","$ENV{SERVER_VAR}/lib/solver_list") or system("mv $ENV{SERVER_TMP}/$$ $ENV{SERVER_VAR}/lib/solver_list");

# Generate Web pages


if ($ENV{SERVER_WWW_READY}) { 
  #Do not create web pages for kestrel solvers
  if($TYPE !~ /^KESTREL_/) {
    print "Updating WEB/CGI area:\n\n"; &flush(STDOUT);
    system("cd $ENV{SERVER_BIN}; echo a | $ENV{SERVER_PERL} make-solver.pl $TYPE:$TOKEN > /dev/null")
      and die "$0: can't create $ENV{SERVER_WWW_HOME}/$TYPE:$TOKEN web pages";
    system("cd $ENV{SERVER_BIN}; $ENV{SERVER_PERL} make-server-solvers.pl   > $ENV{SERVER_WWW_HOME}/server-solvers.html") 
      and die "$0: can't create $ENV{SERVER_WWW_HOME}/server-solvers.html\n";
    if($ENV{SERVER_SOLVER_GROUPS}) {
      system("cd $ENV{SERVER_BIN}; $ENV{SERVER_PERL} make-server-solvers-in.pl   > $ENV{SERVER_WWW_HOME}/server-solvers-in.html") 
        and die "$0: can't create $ENV{SERVER_WWW_HOME}/server-solvers-in.html\n";
    }
  } 
}

# Write to job.results

open(CONFIRM, ">>job.results");
$HOMEPAGE = "$ENV{SERVER_WWW_URL}/solvers/$TYPE:$TOKEN";
write CONFIRM;
close(CONFIRM);

format CONFIRM =

Congratulations!  You have successfully completed the first step
to adding a new solver. The following solver has been registered 
with this server:

Solver Type:       ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$TYPE
Solver Identifier: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$TOKEN
Solver Name:       ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$TITLE
Contact Person:    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$CONTACT
@*
$still_need

Currently, all user interfaces have access to your solver.  The 
"Enabling/Disabling a Solver" solver may be used if you need to 
take your solver off-line.  

If you have not already done so, you must now complete the second
step to adding a solver:   

1) Download the Client Package from: 
   @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$ENV{SERVER_FTP_URL}
2) Install the Client Package.  
3) Start a communications daemon (comms-daemon) on each of the 
   following workstations:

@*
$STATIONS

Instructions on installation and starting the daemons are included 
with the Client Package. Once the communications daemons have been 
started, you will be ready to send jobs to your solver. 

@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$sign
.

sub fail {
  printf ("%25s  %s\n", $_[0], "ERROR");
  &flush(STDOUT);
  open(CONFIRM, ">>job.results");
  print CONFIRM "ERROR: $_[1]\n";
  close(CONFIRM);
  exit;
}

sub fsleep {
  select(undef, undef, undef, $_[0]);
}
