# include "addstar.h"

int resort_unthreaded_parallel (AddstarClientOptions *options, SkyList *sky);

// pass in options and skylist?
int resort_unthreaded_catalogs (AddstarClientOptions *options, SkyList *skylist, int hostID, char *hostpath) {

  off_t i;
  off_t Naverage, Nmeasure;
  Catalog catalog;

  if (PARALLEL && !hostID) {
    resort_unthreaded_parallel (options, skylist);
    return TRUE;
  }

  /* match stars to existing catalog data (or otherwise manipulate catalog data) */
  Naverage = Nmeasure = 0;
  for (i = 0; i < skylist[0].Nregions; i++) {

    // does this host ID match the desired location for the table?
    if (!HostTableTestHost(skylist[0].regions[i], hostID)) continue;

    // chose the catalog file (local or remote?)
    char hostfile[1024];
    snprintf (hostfile, 1024, "%s/%s.cpt", hostpath, skylist[0].regions[i]->name);
    catalog.filename  = hostID ? hostfile : skylist[0].filename[i];

    // set the parameters which guide catalog open/load/create
    catalog.catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
    catalog.catmode   = dvo_catalog_catmode (CATMODE);      // set the default catmode from config data
    catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_LENSING;
    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();

    // an error exit status here is a significant error (disk I/O or file access)
    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
      fprintf (stderr, "ERROR: failure to open/create catalog file %s\n", catalog.filename);
      exit (2);
    }

    // Naves_disk == 0 implies an empty catalog file, skip empty catalogs
    if (catalog.Naves_disk == 0) {
      dvo_catalog_unlock (&catalog);
      dvo_catalog_free (&catalog);
      continue;
    }

    // this is an overloaded value to mean 'force sort'
    if (options->nosort == 3) catalog.sorted = FALSE;

    if (OLD_RESORT) { 
      resort_catalog_old (&catalog);
    } else {
      resort_catalog (&catalog);
    }

    // report total updated values 
    Naverage += catalog.Naverage;
    Nmeasure += catalog.Nmeasure;

    // write out catalog, if appropriate
    SetProtect (TRUE);
    dvo_catalog_save (&catalog, VERBOSE);
    SetProtect (FALSE);
    dvo_catalog_unlock (&catalog);
    dvo_catalog_free (&catalog);
  }
  return TRUE;
}

// CATDIR is supplied globally
# define DEBUG 1
int resort_unthreaded_parallel (AddstarClientOptions *options, SkyList *sky) {

  // load the list of hosts
  HostTable *table = HostTableLoad (CATDIR, sky->hosts);
  if (!table) {
    fprintf (stderr, "ERROR: failure reading Host Table %s for database %s\n", sky->hosts, CATDIR);
    exit (1);
  }    

  int i;
  for (i = 0; i < table->Nhosts; i++) {

    // ensure that the paths are absolute path names
    char *tmppath = abspath (table->hosts[i].pathname, DVO_MAX_PATH);
    free (table->hosts[i].pathname);
    table->hosts[i].pathname = tmppath;

    char command[1024];
    snprintf (command, 1024, "addstar_client -resort -hostID %d -D CATDIR %s -hostdir %s -region %f %f %f %f", 
	      table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, 
	      UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);

    char tmpline[1024];
    if (VERBOSE)                   { snprintf (tmpline, 1024, "%s -v",                command); strcpy (command, tmpline); }
    if (options->nosort == 3)      { snprintf (tmpline, 1024, "%s -force-sort",       command); strcpy (command, tmpline); }
    if (options->existing_regions) { snprintf (tmpline, 1024, "%s -existing-regions", command); strcpy (command, tmpline); }

    fprintf (stderr, "command: %s\n", command);

    if (PARALLEL_MANUAL) continue;

    if (PARALLEL_SERIAL) {
      int status = system (command);
      if (status) {
	fprintf (stderr, "ERROR running addstar_client\n");
	exit (2);
      }
    } else {
      // launch the job on the remote machine (no handshake)
      int errorInfo = 0;
      int pid = rconnect ("ssh", table->hosts[i].hostname, command, table->hosts[i].stdio, &errorInfo, FALSE);
      if (!pid) {
	if (DEBUG) fprintf (stderr, "failure to start %s (error %d)\n", table->hosts[i].hostname, errorInfo);
	exit (1);
      }
      table->hosts[i].pid = pid; // save for future reference
    }
  }

  if (PARALLEL_MANUAL) {
    fprintf (stderr, "run the addstar_client commands above.  when these are done, hit return\n");
    getchar();
  }
  if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
    HostTableWaitJobsGetIO (table, __FILE__, __LINE__, VERBOSE);
  }

  return TRUE;
}      

