# include "relastro.h"
# define DEBUG 0

int strextend (char *input, char *format,...) {

  char tmpextra[1024], tmpline[1024];
  va_list argp;

  va_start (argp, format);
  vsnprintf (tmpextra, 1024, format, argp);
  snprintf (tmpline, 1024, "%s %s", input, tmpextra);
  strcpy (input, tmpline);

  return TRUE;
}

int launch_region_hosts (RegionHostTable *regionHosts) {

  int i;

  // clear the I/O files
  for (i = 0; i < regionHosts->Nhosts; i++) {
    char *syncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "meanmags.sync");
    truncate (syncfile, 0);
    free (syncfile);

    char *fitsfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "meanmags.fits");
    truncate (fitsfile, 0);
    free (fitsfile);

    char *imsyncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "imagemags.sync");
    truncate (imsyncfile, 0);
    free (imsyncfile);

    char *imfitsfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "imagemags.fits");
    truncate (imfitsfile, 0);
    free (imfitsfile);

    char *loopsyncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "loop.sync");
    truncate (loopsyncfile, 0);
    free (loopsyncfile);
  }

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

    RegionHostInfo *host = &regionHosts->hosts[i];

    // communication files:
    // subset images per host : CATDIR/Image.HOSTNAME.fits
    char filename[1024];
    snprintf (filename, 1024, "%s/Image.%d.fits", CATDIR, host->hostID);

    // write the image subset for this host
    ImageTableSave (filename, host->image, host->Nimage);

    char command[1024];
    snprintf (command, 1024, "relastro -parallel-images %s", filename);
    strextend (command, "-region-hosts %s", REGION_FILE);
    strextend (command, "-region-hostID %d", host->hostID);
    strextend (command, "-D CATDIR %s", CATDIR);
    strextend (command, "-region %f %f %f %f", host->RminCat, host->RmaxCat, host->DminCat, host->DmaxCat);
    strextend (command, "-statmode %s", STATMODE);
    strextend (command, "-minerror %f", MIN_ERROR);
    strextend (command, "-nloop %d", NLOOP);
    strextend (command, "-threads %d", NTHREADS);

    switch (FIT_TARGET) {
      case TARGET_SIMPLE:
	strextend (command, "-update-simple");
	break;
      case TARGET_CHIPS:
	strextend (command, "-update-chips");
	break;
      case TARGET_MOSAICS:
	strextend (command, "-update-mosaics");
	break;
      case TARGET_NONE:
	abort();
    }

    if (VERBOSE)       	    strextend (command, "-v");
    if (VERBOSE2)      	    strextend (command, "-vv");
    if (RESET)         	    strextend (command, "-reset");
    if (UPDATE)        	    strextend (command, "-update");
    if (PARALLEL)      	    strextend (command, "-parallel");
    if (PARALLEL_MANUAL)    strextend (command, "-parallel-manual");
    if (PARALLEL_SERIAL)    strextend (command, "-parallel-serial");
    if (PHOTCODE_KEEP_LIST) strextend (command, "+photcode %s", PHOTCODE_KEEP_LIST); 
    if (PHOTCODE_SKIP_LIST) strextend (command, "-photcode %s", PHOTCODE_SKIP_LIST);

    if (MaxDensityUse) 	    strextend (command, "-max-density %f", MaxDensityValue);
    if (ImagSelect)         strextend (command, "-instmag %f %f", ImagMin, ImagMax);
    if (PhotFlagSelect)     strextend (command, "+photflags"); 
    if (PhotFlagBad)        strextend (command, "+photflagbad %d", PhotFlagBad); 
    if (PhotFlagPoor)       strextend (command, "+photflagpoor %d", PhotFlagPoor); 

    if (MinBadQF > 0.0)        strextend (command, "-min-bad-psfqf %f", MinBadQF);
    if (MaxMeanOffset != 10.0) strextend (command, "-max-mean-offset  %f", MaxMeanOffset);

    if (TimeSelect) { 
      char *tstart = ohana_sec_to_date (TSTART);
      char *tstop  = ohana_sec_to_date (TSTOP);
      strextend (command, "-time %s %s", tstart, tstop); 
      free (tstart);
      free (tstop);
    }

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

    // launch the job, then wait for it to be done loading catalogs.  force the remote
    // client to generate the file
    char *syncfile = make_filename (CATDIR, host->hostname, host->hostID, "loadcat.sync");
    clear_sync_file (syncfile);

    // launch the job on the remote machine (no handshake)
    int errorInfo = 0;
    int pid = rconnect ("ssh", host->hostname, command, host->stdio, &errorInfo, FALSE);
    if (!pid) {
      if (DEBUG) fprintf (stderr, "failure to start %s (error %d)\n", host->hostname, errorInfo);
      exit (1);
    }
    host->pid = pid; // save for future reference

    // remove client is done, go ahead with next client
    check_sync_file (syncfile, 1);
    free (syncfile);
  }

  if (PARALLEL_REGIONS_MANUAL) {
    fprintf (stderr, "run the relastro_client commands above.  when these are done, hit return\n");
    getchar();
  } else {
    RegionHostTableWaitJobsGetIO (regionHosts, __FILE__, __LINE__, VERBOSE);
  }
 
  int status = TRUE;
  for (i = 0; i < regionHosts->Nhosts; i++) {
    status = status && (regionHosts->hosts[i].status == 0);
  }

  return status;
}
