# include "addstar.h"

/* these variables are needed by Shutdown */
static FILE *f = (FILE *) NULL;
static int Protect = FALSE;
static int Trapped = FALSE;

/* clean up open / locked ImageCat before shutting down */
int Shutdown () {  
  int dbstate;

  Protect = TRUE;
  fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
  fprintf (stderr, "ERROR: addstar halted\n");
  exit (1);
}

void TrapSignal (int sig) {
    fprintf (stderr, "trapped signal %d, exiting gracefully\n", sig);
    if (sig == 11) {
      fprintf (stderr, "seg fault\n");
      exit (1);
    }
    if (Protect) {
      Trapped = TRUE;
      fprintf (stderr, "blocking until protected sections are clear\n");
      return;
    }
    Shutdown ();
}    

int main (int argc, char **argv) {

  int i, mode, dbstate;
  int Nstars, Nimage, Nregions, Nmissed;
  Stars *stars, *gstars();
  Image image, *pimage, *gimages();
  GSCRegion *region, *gregions();
  Catalog catalog;
  
  SetSignals ();
  args (argc, argv);

  /* load the input datafile */
  stars = gstars (argv[1], &Nstars, &image);
  if (Nstars == 0) {
    if (VERBOSE) fprintf (stderr, "no stars in data file, skipping\n");
    fprintf (stderr, "SUCCESS\n");
    exit (0);
  }

  /* lock the image catalog */
  check_permissions (ImageCat);
  f = fsetlockfile (ImageCat, 3600.0, LCK_HARD, &dbstate);
  if ((f == (FILE *) NULL) && (dbstate != LCK_EMPTY)) {
    fprintf (stderr, "ERROR: can't lock image catalog\n");
    exit (1);
  }
  fseek (f, 0, SEEK_SET);

  /* load images */
  if (dbstate == LCK_EMPTY) {
    Nimage = 0;
  } else {
    pimage = gimages (f, &image, &Nimage);
  }
  region = gregions (&image, &Nregions);
  fprintf (stderr, "region %f %f %f %f\n", region[0].RA[0], region[0].RA[1], region[0].DEC[0], region[0].DEC[1]);

  for (i = 0; i < Nregions; i++) {
    check_permissions (region[i].filename);
  }

  if (CALIBRATE) { InitCalibration (); }

  for (i = 0; i < Nregions; i++) {
    catalog.filename = region[i].filename;  /* don't free region before catalog! */
    fprintf (stderr, "adding to %s\n", region[i].filename);
    
    switch (lock_catalog (&catalog, LCK_XCLD)) {
    case 0:
      /* this is a serious error because ImageCat was NOT locked */
      fprintf (stderr, "ERROR: can't lock file %s\n", catalog.filename);
      exit (1);
    case 1:
      gcatalog (&catalog); /* load from disk */
      break;
    case 2:
      mkcatalog (&region[i], &catalog); /* fills in new header info */
      break;
    }
    find_matches (&region[i], stars, Nstars, &catalog, &image, pimage, Nimage);

    /* protect wcatalog from interrupt signals */
    Protect = TRUE;
    if (!DUMP_MATCHES && !ONLY_IMAGES) wcatalog (&catalog);
    if (Trapped) Shutdown ();
    Protect = FALSE;
    unlock_catalog (&catalog);
  }

  if (CALIBRATE) { FindCalibration (&image); }
  if (DUMP_MATCHES) Shutdown ();

  for (Nmissed = i = 0; i < Nstars; i++) {
    if (stars[i].found == -1) {
      fprintf (stderr, "%d %f %f %f %f\n", i, stars[i].R, stars[i].D, stars[i].M, stars[i].dM);
      Nmissed ++;
    }
  }
  if (Nmissed) fprintf (stderr, "WARNING: %d stars in image were missed!\n", Nmissed);

  /* protect wimage from interrupt signals */
  Protect = TRUE;
  wimage (f, dbstate, &image, Nstars); 
  if (Trapped) Shutdown ();
  Protect = FALSE;

  fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);

  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
  chmod (ImageCat, mode);

  fprintf (stderr, "SUCCESS\n");
  exit (0);

}

int SetSignals () {

  int i;

  /* disable almost all signal interrupts */
  for (i = 0; i < 36; i++) {
    switch (i) {
      /* can't redirect this signals */
    case SIGKILL:    /* kill -9: cannot be caught or ignored */
    case SIGSTOP:    /* SIGSTOP: cannot be caught or ignored */
      /* ignore these signals */
    case SIGCHLD:    /* child halted: ignore */
    case SIGPWR:     /* power failure - why ignore this? */
    case SIGWINCH:   /* window resized */
    case SIGCONT:    /* continue - maintain this action */
    case SIGTSTP:    /* stop signal sent from tty - why ignore? */
    case SIGURG:     /* socket signal, ignore this */
      break;
      
    default:
      signal (i, TrapSignal);
    }
  }
  return (TRUE);
}
/*

       Signal     Value     Action   Comment
       -------------------------------------------------------------------------
       SIGHUP        1        A      Hangup detected on controlling terminal
                                     or death of controlling process
       SIGINT        2        A      Interrupt from keyboard
       SIGQUIT       3        A      Quit from keyboard
       SIGILL        4        A      Illegal Instruction
       SIGABRT       6        C      Abort signal from abort(3)
       SIGFPE        8        C      Floating point exception
       SIGKILL       9       AEF     Kill signal
       SIGSEGV      11        C      Invalid memory reference
       SIGPIPE      13        A      Broken pipe: write to pipe with no readers
       SIGALRM      14        A      Timer signal from alarm(2)
       SIGTERM      15        A      Termination signal
       SIGUSR1   30,10,16     A      User-defined signal 1
       SIGUSR2   31,12,17     A      User-defined signal 2
       SIGCHLD   20,17,18     B      Child stopped or terminated
       SIGCONT   19,18,25            Continue if stopped
       SIGSTOP   17,19,23    DEF     Stop process
       SIGTSTP   18,20,24     D      Stop typed at tty
       SIGTTIN   21,21,26     D      tty input for background process
       SIGTTOU   22,22,27     D      tty output for background process

       Next various other signals.

       Signal       Value     Action   Comment
       ---------------------------------------------------------------------
       SIGTRAP        5         CG     Trace/breakpoint trap
       SIGIOT         6         CG     IOT trap. A synonym for SIGABRT
       SIGEMT       7,-,7       G
       SIGBUS      10,7,10      AG     Bus error
       SIGSYS      12,-,12      G      Bad argument to routine (SVID)
       SIGSTKFLT    -,16,-      AG     Stack fault on coprocessor
       SIGURG      16,23,21     BG     Urgent condition on socket (4.2 BSD)
       SIGIO       23,29,22     AG     I/O now possible (4.2 BSD)
       SIGPOLL                  AG     A synonym for SIGIO (System V)
       SIGCLD       -,-,18      G      A synonym for SIGCHLD
       SIGXCPU     24,24,30     AG     CPU time limit exceeded (4.2 BSD)
       SIGXFSZ     25,25,31     AG     File size limit exceeded (4.2 BSD)
       SIGVTALRM   26,26,28     AG     Virtual alarm clock (4.2 BSD)
       SIGPROF     27,27,29     AG     Profile alarm clock
       SIGPWR      29,30,19     AG     Power failure (System V)
       SIGINFO      29,-,-      G      A synonym for SIGPWR
       SIGLOST      -,-,-       AG     File lock lost
       SIGWINCH    28,28,20     BG     Window resize signal (4.3 BSD, Sun)
       SIGUNUSED    -,31,-      AG     Unused signal
       (Here - denotes that a signal is absent; there where three values are given, the first one is usually  valid  for  alpha  and
       sparc,  the  middle  one  for i386 and ppc, the last one for mips. Signal 29 is SIGINFO / SIGPWR on an alpha but SIGLOST on a
       sparc.)

       The letters in the "Action" column have the following meanings:

       A      Default action is to terminate the process.

       B      Default action is to ignore the signal.

       C      Default action is to dump core.

       D      Default action is to stop the process.

       E      Signal cannot be caught.

       F      Signal cannot be ignored.

       G      Not a POSIX.1 conformant signal.

*/
