# include "relastro.h"

/* This function is essentially identical to relastro_images, except:

 * load the subset images saved by the master node
 * distinguish detections we own (touch our images) and those we don't
 * distinguish objects we own (in region) and those we don't
 * update the unowned detections for owned objects from neighbor regions
 * update the unowned objects for owned detections 
 */

int relastro_parallel_images () {

  int i, Ncatalog;
  Catalog *catalog = NULL;

  INITTIME;

  // load the RegionTable (UserRegion should not be used at this level)
  RegionHostTable *regionHosts = RegionHostTableLoad (CATDIR, REGION_FILE);
  int myHost = regionHosts->index[REGION_HOST_ID];
  RegionHostFindNeighbors (regionHosts, myHost);

  // load the subset images belonging to this host
  off_t Nimage;
  Image *image = ImageTableLoad (IMAGE_TABLE, &Nimage);
  if (!image) {
    fprintf (stderr, "ERROR loading image %s\n", IMAGE_TABLE);
    exit (2);
  }

  // once we have read this table, we should remove it for repeat runs
  // unlink (IMAGE_TABLE); // XXX a bit risky, add some protection?

  // XXX need to deal with mosaic vs image...
  initMosaics (image, Nimage);

  initImages (image, NULL, Nimage);

  SkyTable *sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
  SkyTableSetFilenames (sky, CATDIR, "cpt");
  SkyList *skylist = SkyListByBounds (sky, -1, UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);

  initCoords();

  /* load catalog data from region files (hostID is 0 since we are not a client */
  char *syncfile = make_filename (CATDIR, regionHosts->hosts[myHost].hostname, REGION_HOST_ID, "loadcat.sync");
  catalog = load_catalogs (skylist, &Ncatalog, TRUE, 0, NULL, syncfile);
  MARKTIME("-- load catalog data: %f sec\n", dtime);
  free (syncfile);
  
  if (photcodesReset) {
    photcodesKeep  = photcodesReset;
    NphotcodesKeep = NphotcodesReset;
  }

  // generate tables go from catID,objID -> catSeq,objSeq
  indexCatalogs (catalog, Ncatalog);

  /* match measurements with images, mosaics */
  initImageBins  (catalog, Ncatalog, TRUE);
  MARKTIME("-- make image bins: %f sec\n", dtime);

  findImages (catalog, Ncatalog, TRUE);
  MARKTIME("-- set up image indexes: %f sec\n", dtime);

  // set test points based on the starmap
  createStarMap (catalog, Ncatalog);

  markObjects (catalog, Ncatalog);

  SAVEPLOT = FALSE;

  /* major modes */
  switch (FIT_TARGET) {
    case TARGET_SIMPLE:
      for (i = 0; i < NLOOP; i++) {
	UpdateObjects (catalog, Ncatalog);
	share_mean_pos (catalog, Ncatalog, regionHosts, i);
	slurp_mean_pos (catalog, Ncatalog, regionHosts, i);
	UpdateSimple (catalog, Ncatalog);
	share_image_pos (regionHosts, i);
	slurp_image_pos (regionHosts, i);
      }
      break;

    case TARGET_CHIPS:
      for (i = 0; i < NLOOP; i++) {
	UpdateObjects (catalog, Ncatalog);
	share_mean_pos (catalog, Ncatalog, regionHosts, i);
	slurp_mean_pos (catalog, Ncatalog, regionHosts, i);
	UpdateChips (catalog, Ncatalog);
	share_image_pos (regionHosts, i);
	slurp_image_pos (regionHosts, i);
	MARKTIME("update chips: %f sec\n", dtime);
      }
      // create summary plots of the process
      // relastroVisualSummaryChips();
      break;

    case TARGET_MOSAICS:
      for (i = 0; i < NLOOP; i++) {
	UpdateObjects (catalog, Ncatalog);
	share_mean_pos (catalog, Ncatalog, regionHosts, i);
	slurp_mean_pos (catalog, Ncatalog, regionHosts, i);
	UpdateMosaic (catalog, Ncatalog);
	share_image_pos (regionHosts, i);
	slurp_image_pos (regionHosts, i);
      }
      break;

    default:
      fprintf (stderr, "programming error at %s:%d", __FILE__, __LINE__);
      exit (2);
  }

  // this is a checkpoint to make sure all hosts have finished the loop above
  char *loopsyncfile = make_filename (CATDIR, regionHosts->hosts[myHost].hostname, REGION_HOST_ID, "loop.sync");
  update_sync_file (loopsyncfile, 0);
  free (loopsyncfile);

  for (i = 0; i < regionHosts->Nhosts; i++) {
    if (regionHosts->hosts[i].hostID == REGION_HOST_ID) continue;
    char *loopsync = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "loop.sync");
    check_sync_file (loopsync, 0);
    free (loopsync);
  }    

  share_image_pos (regionHosts, -1);

  exit (0);
}
