/* $Id: staff.pc 4066 2012-01-19 21:44:57Z zacheiss $
 *
 * Load data into Moira from Personnel Office data file
 *
 * Copyright (C) 1990-1998 by the Massachusetts Institute of Technology
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 */

#include <mit-copyright.h>
#include <moira.h>
#include <moira_site.h>
#include <moira_schema.h>
#include "common.h"

#include <ctype.h>
#include <stdio.h>
#include <string.h>

EXEC SQL INCLUDE sqlca;

RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/regtape/staff.pc $ $Id: staff.pc 4066 2012-01-19 21:44:57Z zacheiss $");

/* File format is:
 *
 * id number [9]
 * last name [30]
 * first name [30]
 * middle name [30]
 * office address [24]
 * phone1 [12]
 * phone2 [12]
 * dept [50]
 * title [50]
 */

#define LOC_ID 0
#define LEN_ID 9
#define LOC_LAST_NAME (LOC_ID + LEN_ID)
#define LEN_LAST_NAME 30
#define LOC_FIRST_NAME (LOC_LAST_NAME + LEN_LAST_NAME)
#define LEN_FIRST_NAME 30
#define LOC_MIDDLE_NAME (LOC_FIRST_NAME + LEN_FIRST_NAME)
#define LEN_MIDDLE_NAME 30
#define LOC_OFFICE (LOC_MIDDLE_NAME + LEN_MIDDLE_NAME)
#define LEN_OFFICE 24
#define LOC_PHONE (LOC_OFFICE + LEN_OFFICE)
#define LEN_PHONE 12
#define LOC_PHONE2 (LOC_PHONE + LEN_PHONE)
#define LEN_PHONE2 12
#define LOC_DEPT (LOC_PHONE2 + LEN_PHONE2)
#define LEN_DEPT 50
#define LOC_TITLE (LOC_DEPT + LEN_DEPT)
#define LEN_TITLE 50

struct entry *get_next_entry(FILE *in);
void process_entry(struct entry *e, int secure);

EXEC SQL BEGIN DECLARE SECTION;
int who;
char *prog = "stafload";
EXEC SQL END DECLARE SECTION;

char *whoami;

int main(int argc, char **argv)
{
  FILE *in;
  struct entry *e;
  int i, wait = 0;
  char buf[80], *file = NULL;
  EXEC SQL BEGIN DECLARE SECTION;
  char *db = "moira";
  EXEC SQL END DECLARE SECTION;

  whoami = strrchr(argv[0], '/');
  if (whoami)
    whoami++;
  else
    whoami = argv[0];

  setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
  setvbuf(stderr, NULL, _IOLBF, BUFSIZ);

  for (i = 1; i < argc; i++)
    {
      if (!strcmp(argv[i], "-w"))
	wait++;
      else if (file)
	{
	  fprintf(stderr, "Usage: %s [-w] inputfile\n", whoami);
	  exit(1);
	}
      else
	file = argv[i];
    }

  if (!file)
    {
      fprintf(stderr, "Usage: %s [-w] inputfile\n", whoami);
      exit(1);
    }

  in = fopen(file, "r");
  if (!in)
    {
      fprintf(stderr, "Unable to open %s for input\n", file);
      exit(1);
    }

  initialize_sms_error_table();

  EXEC SQL CONNECT :db IDENTIFIED BY :db;
  if (sqlca.sqlcode)
    {
      dbmserr("opening database", sqlca.sqlcode);
      exit(1);
    }

  EXEC SQL SELECT users_id INTO :who FROM users WHERE login = 'root';

  while ((e = get_next_entry(in)))
    {
      process_entry(e, 0);
      EXEC SQL COMMIT WORK;
      if (sqlca.sqlcode)
	{
	  dbmserr("committing work", sqlca.sqlcode);
	  exit(1);
	}
      if (wait)
	{
	  printf("Next");
	  fflush(stdout);
	  fgets(buf, sizeof(buf), stdin);
	}
    }

  exit(0);
}

struct entry *get_next_entry(FILE *in)
{
  static struct entry e;
  static char buf[BUFSIZ];
  static char last_name[LEN_LAST_NAME + 1], id[LEN_ID + 1];
  static char first_name[LEN_FIRST_NAME + 1], middle_name[LEN_MIDDLE_NAME + 1];
  static char office[LEN_OFFICE + 1], phone[LEN_PHONE + 1];
  static char phone2[LEN_PHONE2 + 1], dept[LEN_DEPT + 1], title[LEN_TITLE + 1];
  int ends_sr, ends_jr, ends_iii, ends_iv, ends_ii, ends_v;
  char *p, *q;

  if (!fgets(buf, sizeof(buf), in))
    return NULL;

  strlcpy(id, &buf[LOC_ID], LEN_ID + 1);
  strlcpy(last_name, &buf[LOC_LAST_NAME], LEN_LAST_NAME + 1);
  strlcpy(first_name, &buf[LOC_FIRST_NAME], LEN_FIRST_NAME + 1);
  strlcpy(middle_name, &buf[LOC_MIDDLE_NAME], LEN_MIDDLE_NAME + 1);
  strlcpy(office, &buf[LOC_OFFICE], LEN_OFFICE + 1);
  strlcpy(phone, &buf[LOC_PHONE], LEN_PHONE + 1);
  strlcpy(phone2, &buf[LOC_PHONE2], LEN_PHONE2 + 1);
  strlcpy(dept, &buf[LOC_DEPT], LEN_DEPT + 1);
  strlcpy(title, &buf[LOC_TITLE], LEN_TITLE + 1);

  e.last = strtrim(last_name);
  e.first = strtrim(first_name);
  e.middle = strtrim(middle_name);

  ends_sr = ends_jr = ends_iii = ends_iv = ends_ii = ends_v = 0;
  LookForSt(e.last);
  LookForO(e.last);
  LookForJrAndIII(e.last, &ends_jr, &ends_sr, &ends_ii, &ends_iii,
		  &ends_iv, &ends_v);
  LookForJrAndIII(e.first, &ends_jr, &ends_sr, &ends_ii, &ends_iii,
		  &ends_iv, &ends_v);

  e.name = buf;
  if (*e.middle)
    sprintf(e.name, "%s %s %s", e.first, e.middle, e.last);
  else
    sprintf(e.name, "%s %s", e.first, e.last);

  e.id = id;
  e.haddr = e.hphone = "";

  /* Not used for employees. */
  e.reg_type = "";

  /* The following is really gross, but it happens to successfully convert
   * new-style Warehouse office descriptions into (more-readable) old-style
   * Personnel Office office descriptions.
   */
  e.oaddr = p = strtrim(office);
  while (*p && !isspace(*p))
    p++;
  q = p;
  while (isspace(*q))
    q++;
  if (*q && q < e.oaddr + LEN_OFFICE / 2)
    {
      *p++ = '-';
      while (*q && q < e.oaddr + LEN_OFFICE / 2)
	{
	  if (*q != ' ' && *q != '-')
	    *p++ = *q;
	  if (q > p)
	    *q = ' ';
	  q++;
	}
      memset(p, ' ', q - p);
    }

  p = e.oaddr + LEN_OFFICE / 2;
  while (*p && !isspace(*p))
    p++;
  q = p;
  while (isspace(*q))
    q++;
  if (*q)
    {
      *p++ = '-';
      while (*q)
	{
	  if (*q != ' ' && *q != '-')
	    *p++ = *q;
	  if (q > p)
	    *q = ' ';
	  q++;
	}
      memset(p, ' ', q - p);
    }
  strtrim(e.oaddr);
  fixaddress(e.oaddr);
  e.xaddress = e.oaddr;

  e.ophone = e.xphone1 = strtrim(phone);
  fixphone(e.ophone);
  e.xphone2 = strtrim(phone2);
  fixphone(e.xphone2);
  e.dept = strtrim(dept);
  e.xtitle = strtrim(title);

  e.type = "MITS";
  if ((strstr(uppercase(e.xtitle), "PROF") &&
       !strstr(uppercase(e.xtitle), "PROFESSION")) ||
      strstr(uppercase(e.xtitle), "LECTURE"))
    e.type = "FACULTY";
  if (strstr(uppercase(e.dept), "LINCOLN LAB"))
    e.type = "LINCOLN";

  FixCase(e.dept);
  FixCase(e.xtitle);

  return &e;
}
