#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <pslib.h>
#include <psmodules.h>
#include <ppStats.h>

#include "ppStack.h"
#include "ppStackLoop.h"

bool ppStackFinish(ppStackOptions *options, pmConfig *config)
{
    psAssert(options, "Require options");
    psAssert(config, "Require configuration");

    psThreadPoolFinalize();

    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
    psAssert(recipe, "We've thrown an error on this before.");

    // Statistics on output
    if (options->stats) {
        psTrace("ppStack", 1, "Gathering statistics on stacked image....\n");
        psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits for bad
        psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels

        pmFPAview *view = pmFPAviewAlloc(0); // View to readout
        view->chip = view->cell = view->readout = 0;

        ppStatsFPA(options->stats, options->outRO->parent->parent->parent, view, maskBad, config);

        psFree(view);
    }

    ppStackMemDump("stats");

    psFree(options->outRO); options->outRO = NULL;

    // Write out the output files
    if (!ppStackFilesIterateUp(config)) {
        return false;
    }


    // Write out summary statistics
    if (options->stats) {
        psMetadataAddF32(options->stats, PS_LIST_TAIL, "TIME_STACK", 0,
                         "Total time", psTimerClear("PPSTACK_TOTAL"));

        const char *statsMDC = psMetadataConfigFormat(options->stats);
        if (!statsMDC || strlen(statsMDC) == 0) {
            psError(PS_ERR_IO, false, "Unable to get statistics MDC file.\n");
        } else {
            fprintf(options->statsFile, "%s", statsMDC);
        }
        psFree((void *)statsMDC);
        fclose(options->statsFile); options->statsFile = NULL;
        pmConfigRunFilenameAddWrite(config, "STATS", psMetadataLookupStr(NULL, config->arguments, "STATS"));
    }


    // Dump configuration
    bool mdok;                          // Status of MD lookup
    psString dump = psMetadataLookupStr(&mdok, config->arguments, "DUMP_CONFIG"); // File for config
    if (dump) {
        pmConfigDump(config, dump);
    }

    return true;
}
