# include "delstar.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: delstar 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 ();
}    

main (int argc, char **argv) {

  int i, j, k, found, Nimage, Nregions, Ntregions, NREGIONS;
  int start, end, dbstate;
  Image *image, *gimages(), *gtimes(), *find_images();
  Catalog catalog;
  CatStats catstats;
  GSCRegion *region, *tregion, *gregions();
  
  SetSignals ();
  args (&argc, argv);

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

  /* delete orphaned measurements (no image) from catalog */ 
  if (ORPHAN) {
    ALLOCATE (region, GSCRegion, 1);
    catalog.filename = argv[1];
    gcatalog (&catalog);
    gcatstats (&catalog, &catstats);
    image = find_images (f, &catstats, &Nimage);
    match_images (&catalog, image, Nimage);
    delete_orphans (&catalog);
    wcatalog (&catalog);
    fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
    fprintf (stderr, "SUCCESS\n");
    exit (0);
  } 

  /* delete missed measurements from catalog */ 
  if (MISSED) {
    catalog.filename = argv[1];
    switch (lock_catalog (&catalog, LCK_XCLD)) {
    case 0:
      fprintf (stderr, "ERROR: can't lock file\n");
      exit (1);
    case 1:
      gcatalog (&catalog);
      break;
    case 2:
      fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
      catalog.Naverage = 0;
      catalog.Nmeasure = 0;
      break;
    default:
      fprintf (stderr, "weird lock_catalog exit state\n");
      exit (1);
    }
    delete_missed (&catalog);
    wcatalog (&catalog);
    fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
    fprintf (stderr, "SUCCESS\n");
    exit (0);
  } 

  /* delete given image from catalogs */
  if (argc == 2) {
    image = gimages (argv[1]);
  
    fprintf (stderr, "deleting %s\n", image[0].name);
    region = gregions (&image[0], &Nregions);

    for (i = 0; i < Nregions; i++) {
      fprintf (stderr, "deleting from %s\n", region[i].filename);
      catalog.filename = region[i].filename;  /* don't free region before catalog! */
      switch (lock_catalog (&catalog, LCK_SOFT)) {
      case 0:
	fprintf (stderr, "ERROR: can't lock file\n");
	exit (1);
      case 1:
	gcatalog (&catalog);
	break;
      case 2:
	fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
	catalog.Naverage = 0;
	catalog.Nmeasure = 0;
	break;
      default:
	fprintf (stderr, "weird lock_catalog exit state\n");
	exit (1);
      }
      find_matches (&catalog, &image[0], 0, 0);
      wcatalog (&catalog);
    }

    dimages (f, image, 1); 
    fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
    fprintf (stderr, "SUCCESS\n");
    exit (0);
  }

  /* delete measurements in time range */
  if (argc == 3) {
    Nregions = 0;
    NREGIONS = 10;
    ALLOCATE (region, GSCRegion, NREGIONS);

    /* find image for time range, delete each image */ 
    image = gtimes (f, argv, &Nimage, &start, &end);
    for (j = 0; j < Nimage; j++) {
      fprintf (stderr, "finding regions for %s\n", image[j].name);
      tregion = gregions (&image[j], &Ntregions);
      for (i = 0; i < Ntregions; i++) {
	found = FALSE;
	for (k = 0; (k < Nregions) && !found; k++) {
	  found = !strcmp (region[k].filename, tregion[i].filename);
	}
	if (!found) {
	  strcpy (region[Nregions].filename, tregion[i].filename);
	  region[Nregions].RA[0] = tregion[i].RA[0];
	  region[Nregions].RA[1] = tregion[i].RA[1];
	  region[Nregions].DEC[0] = tregion[i].DEC[0];
	  region[Nregions].DEC[1] = tregion[i].DEC[1];
	  Nregions ++;
	  if (Nregions >= NREGIONS) {
	    NREGIONS += 10;
	    REALLOCATE (region, GSCRegion, NREGIONS);
	  }
	}
      }
    }
    for (i = 0; i < Nregions; i++) {
      fprintf (stderr, "deleting from %s\n", region[i].filename);
      catalog.filename = region[i].filename;  /* don't free region before catalog! */
      switch (lock_catalog (&catalog, LCK_SOFT)) {
      case 0:
	fprintf (stderr, "ERROR: can't lock file\n");
	exit (1);
      case 1:
	gcatalog (&catalog);
	break;
      case 2:
	fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
	catalog.Naverage = 0;
	catalog.Nmeasure = 0;
	break;
      default:
	fprintf (stderr, "weird lock_catalog exit state\n");
	exit (1);
      }
      find_matches (&catalog, &image[0], start, end);
      wcatalog (&catalog);
    }
    dimages (f, image, Nimage);
    fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
    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);
    }
  }

}
