static char *rcsid = "$Header: /sanguine/homes/zeus/Blind-2.48/server/RCS/order.c,v 2.48 1999/03/14 01:06:05 zeus Exp zeus $";

/*
 * $Log: order.c,v $
 * Revision 2.48  1999/03/14 01:06:05  zeus
 * *** empty log message ***
 *
 */

#define NOTIMEB
#include "common.h"
#include "prototypes.h"
#include "findplayer.h"
#include "order.h"
#include <errno.h>
#include "exit.h"

#ifdef GAMENAME
char gamename[MAXTEXT];

#endif



player *players;
char buf[256];
char err_tmp[2 * MAXSTRLEN + 1];
porder * orders_order;
char From[MAXSTRLEN], Subject[MAXSTRLEN], Date[MAXSTRLEN];
char galaxy_line[MAXSTRLEN];
char turn[MAXTEXT];

void order_rcsid (void);

void
order_rcsid (void)
{
  printf ("%s\n", rcsid);
}

void 
match_order_line(void)
{
  FILE * outfile;
  int flag;
  player * P;
  porder *p;
  char name[MAXTEXT+7]; /* Orders file, name lens plus . and orders */

  P = n2inputplayer("");
  if (P==NULL)
  {
    debug(err_tmp);
    return;
  }
  /* OK, we've got the headers, have a valid player #galaxy line, etc */
  sprintf (name,"%s.orders",P->name);
  outfile=fopen (name,"w");
  if (outfile==0)
  {
    fprintf (stderr,"Can't open %s (%s)\n", name,strerror (errno));
    exit (ORDERFAIL);
  }


  if (strlen(galaxy_line)==0)
  {
    fprintf (stderr,"Missing #galaxy line, code probably miscompiled!\n");
    assert(0);
  }
  fprintf (outfile,"%s\n%s\n%s\n\n%s\n",From,Date,Subject,galaxy_line);
  
  /* Update Player ordering list */
  /* First see if we've seen any orders at all; if so then see if this
     is a replacement set (they are in the orders_order list) in which 
     case they need to be removed 
     (BUG: should really just reorder this, but I'm lazy) or maybe
     make doubly linked list and traverse once at end to weed out dups? */
  if (orders_order != (porder *)NULL)
  {
    if (strcmp(orders_order->name,P->name)==0)
    { /* Begining of list case */
      sprintf (err_tmp,"Updating orders for %s\n",P->name);
      p=orders_order;
      orders_order=orders_order->next;
      free (p);
      debug(err_tmp);
    }
    else
    {
      for (p=orders_order;p;p=p->next)
      { /* Middle of list case */
        if (strcmp(p->name,P->name)==0)
        {
          sprintf (err_tmp,"Updating orders for %s\n",P->name);
          removelist (orders_order,p);
          debug(err_tmp);
        }
      }
    }
  }

  /* Add this to the list of seen order sets */
  p=(porder *)alloc(sizeof(porder));
  hstrcpy (p->name,P->name);
  addlist (&orders_order,p);
  for (;;)
  {
    fgets (buf,MAXSTRLEN-1,stdin);
    if (feof (stdin))
    {
      fprintf (stderr,"Missing #end, assuming that it is there\n");
      fprintf (outfile, "#end\n");
      fclose(outfile);
      return;
    }
    if (hstricmp("#end\n",buf)==0)
    {
      fprintf (outfile, "#end\n");
      fclose(outfile);
      return;
    }
    fprintf (outfile, "%s",buf);
  }
}

/* Look for the next set of orders, basically:
  Store Date, From, Subject headers;
  if we hit the body of the message (^$ and Date/From/Subject all set
  then call match_order line to find the #galaxy line */
void
next_set(void)
{
  const char from[] = "From:", subject[] = "Subject:", date[] = "Date:";
  int sfrom,ssubject,sdate,flag,body;

  sfrom=ssubject=sdate=body=0;
  for (flag=0;(flag==0)&&(!feof(stdin));)
  {
    fgets (buf,MAXSTRLEN-1,stdin);

    /* Do this here to do body shortcircut correctly */
    if (buf[1]=='\0') body=1;

    if ((body==1)&&(sfrom&&ssubject&&sdate))
    { /* We are now in the body of the message */
      match_order_line();
      return;
    }

    if (strncmp (buf,from,5)==0)
    {
      if (sfrom)
      {
        sprintf (err_tmp,"Replacing `%s' with %s",From,buf);
        debug(err_tmp);
      }
      hcstrncpy(From,buf,MAXSTRLEN);
      From[strlen(From)-1]='\0';
      sfrom=1;
    }
    if (strncmp (buf,subject,8)==0)
    {
      if (ssubject)
      {
        sprintf (err_tmp,"Replacing `%s' with %s",Subject,buf);
        debug(err_tmp);
      }
      hcstrncpy(Subject,buf,MAXSTRLEN);
      Subject[strlen(Subject)-1]='\0';
      ssubject=1;
    }
    if (strncmp (buf,date,5)==0)
    {
      if (sdate)
      {
        sprintf (err_tmp,"Replacing `%s' with %s",Date,buf);
        debug(err_tmp);
      }
      hcstrncpy(Date,buf,MAXSTRLEN);
      Date[strlen(Date)-1]='\0';
      sdate=1;
    }
  } 
}


void
build_master_order_file (void)
{
  porder *p;
  char masterfile[MAXSTRLEN];
  char orderfile[MAXTEXT+7];
  FILE *outfile, *infile;

  sprintf (masterfile,"%sOrders.%s",gamename,turn);
  outfile=fopen (masterfile,"w");
  if (outfile==0)
  {
    fprintf (stderr,"Can't open %s (%s)\n", masterfile,strerror (errno));
    exit (ORDERFAIL);
  }
  fprintf (outfile,"Master orders for %s, turn %s\n",gamename,turn);
  fprintf (outfile,"Orders sequence:\n");
  for (p=orders_order;p;p=p->next)
  {
    fprintf (outfile,"%s\n",p->name);
  }
  fprintf (outfile,"\n\n\n");

  /* Open and copy */
  for (p=orders_order;p;p=p->next)
  {
    sprintf (orderfile,"%s.orders",p->name);
    infile=fopen (orderfile,"r");
    if (infile==0)
    {
      fprintf (stderr,"Can't open %s (%s)\n", orderfile,strerror (errno));
      exit (ORDERREOPEN);
    }
    for (;;)
    { /* Do copy here */
      char line[MAXSTRLEN];

      fgets (line,MAXSTRLEN,infile);
      if (feof(infile))
	break;
      fprintf (outfile,"%s",line);
    }
    fclose (infile);
  }
  fclose(outfile);
  freelist(orders_order);
}





  

int
main (int argc, char *argv[])
{
  porder *p;

  memset (gamename,MAXTEXT,sizeof(char));
  hstrncpy(gamename,getenv ("GAMENAME"),MAXTEXT);
  memset (turn,MAXTEXT,sizeof(char));
  hstrncpy(turn,getenv ("TURN"),MAXTEXT);
  if ((gamename[0]=='\0')  || (turn[0]=='\0'))
  {
    fprintf (stderr,"GAMENAME or TURN unset in env!\n");
    exit(NAMESET);
  }
  load_player_list();

  orders_order=(porder *)NULL;
  do
  {
    next_set();
  }
  while (!feof(stdin));
  
  /* OK, in theory, all orders have been seen, so build the master file... */
  build_master_order_file();
  
  exit (0);
}



void
debug (char *message)
{
#ifdef VERBOSE
  fprintf (stderr,message);
#endif
  return;
}

/* Load the races:player file so we have a list of players */
void 
load_player_list (void)
{
  FILE *pwf, *pwf2;
  char pwl[MAXTEXT + 2 + MAXSTRLEN];    /* BUG: multiple long email @'s */
  int j,z;
  int matched = 0;
  player *P;

  memset (pwl, 0, 5 * MAXTEXT + 1);
  pwf = fopen ("races:players", "r");
  if (pwf == NULL)
  {
    sprintf (buf,"Player file missing!?! (%s)\n",strerror (errno));
    error (buf);
    exit (MISSINGRP);           /* Urk. No file? */
  }
  for (;;)
  {
    /* Do the EOF check first, to deal with empty file and match on last */
    fgets (pwl, MAXSTRLEN - 1, pwf);
    z=strlen (pwl) - 1;
    if (z)
      pwl[z] = '\0';

    if (feof (pwf))             
    {
      fclose(pwf);
      return;
    }
    for (z=0;pwl[z];z++)
    {
      if (pwl[z]==':')
      {
        pwl[z]='\0';
        P= (player *) alloc (sizeof(player));
        hstrncpy(P->name,pwl,MAXTEXT);
        addlist(&players,P);
        break;
      }
    }
  }
}


void *
nametop (void *head, char *s)
{
  list *p;

  for (p = head; p; p = p->next)
    if (!hstricmp ((char *) (p + 1), s))
      return p;
  return 0;
}
