# include "psphotInternal.h"

// for now, let's store the detections on the readout->analysis for each readout
bool psphotReadoutCleanup (pmConfig *config, const pmFPAview *view)
{
    bool status = true;

    // remove internal pmFPAfiles, if created
    if (psErrorCodeLast() == PSPHOT_ERR_DATA) {
        psErrorStackPrint(stderr, "Error in the psphot readout analysis");
        psErrorClear();
    }
    if (psErrorCodeLast() != PS_ERR_NONE) {
        return false;
    }

    // select the appropriate recipe information
    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
    psAssert (recipe, "missing recipe?");

    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");

    // loop over the available readouts
    for (int i = 0; i < num; i++) {
	if (!psphotReadoutCleanupReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
            psError (PSPHOT_ERR_CONFIG, false, "failed on psphotReadoutCleanup for PSPHOT.INPUT entry %d", i);
	    return false;
	}
    }

    // XXX move this to top of loop?
    pmKapaClose ();

    return true;
}

// psphotReadoutCleanup is called on exit from psphotReadout.  If the last raised error is
// not a DATA error, then there was a serious problem.  Only in this case, or if the fail
// on the stats measurement, do we return false
bool psphotReadoutCleanupReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) {

    bool status = true;

    // find the currently selected readout
    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
    psAssert (file, "missing file?");

    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
    psAssert (readout, "missing readout?");

    // when psphotReadoutCleanup is called, these are not necessarily defined
    pmPSF        *psf        = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    psArray      *sources    = detections ? detections->allSources : NULL;
    // XXX where do we free these, in here (psMetadataRemove?)

    // use the psf-model to measure FWHM stats
    if (psf) {
        if (!psphotPSFstats (readout, psf)) {
            psError(PSPHOT_ERR_PROG, false, "Failed to measure PSF shape parameters");
            return false;
        }
    }
    // otherwise, use the source moments to measure FWHM stats
    if (!psf && sources) {
        if (!psphotMomentsStats (readout, sources)) {
            psError(PSPHOT_ERR_PROG, false, "Failed to measure Moment shape parameters");
            return false;
        }
    }

    // Check to see if the image quality was measured
    // XXX not sure we want / need this test
    if (0 && !psf) {
        bool mdok;                      // Status of MD lookup
        int nIQ = psMetadataLookupS32(&mdok, recipe, "IQ_NSTAR"); // Number of stars for IQ measurement
        if (!mdok || nIQ <= 0) {
            psError(PSPHOT_ERR_DATA, false, "Unable to measure image quality");
            return false;
        }
    }

    // create an output header with stats results currently saved on readout->analysis
    psMetadata *header = psphotDefineHeader (readout->analysis);

    // write NSTARS to the image header
    psphotSetHeaderNstars (header, sources);

    // save the results of the analysis
    // this should happen way up stream (when needed?)
    psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.HEADER",  PS_DATA_METADATA, "header stats", header);

    if (psf) {
	// XXX this seems a little silly : we saved the psf on readout->analysis above, but now
	// we are moving it to chip->analysis.
        // save the psf for possible output.  if there was already an entry, it was loaded from external sources
        // the new one may have been updated or modified, so replace the existing entry.  We
        // are required to save it on the chip, but this will cause problems if we ever want to
        // run psphot on an unmosaiced image
        pmCell *cell = readout->parent;
        pmChip *chip = cell->parent;
        psMetadataAdd (chip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN | PS_META_REPLACE,  "psphot psf", psf);
    }

    if (psErrorCodeLast() != PS_ERR_NONE) {
        psErrorStackPrint(stderr, "unexpected remaining errors");
        abort();
    }

    psFree (header);
    return true;
}
