/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set sw=2 sts=2 et cin: */
/*
 * This file is part of the MUSE Instrument Pipeline
 * Copyright (C) 2007-2016 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#define _DEFAULT_SOURCE
#define _BSD_SOURCE /* get setenv() from stdlib.h */
#include <stdlib.h> /* setenv() */

#include <muse.h>

/*----------------------------------------------------------------------------*/
/**
  @brief    short test program to check that muse_cosmics_dcr() does what it
            should when called on (part of) a (simulated) MUSE science exposure
            that has already been bias-corrected and trimmed.
 */
/*----------------------------------------------------------------------------*/
int main(int argc, char **argv)
{
  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_DEBUG);

  muse_image *image = NULL;
  if (argc == 2) {
    /* assume that the file passed on the command line is an input image */
    cpl_msg_info(__func__, "command line argument detected, will try to load %s",
                 argv[1]);
    image = muse_image_load(argv[1]);
  } else {
    image = muse_image_load(BASEFILENAME"_in.fits");
  }

  if (!image->data) {
    cpl_msg_error(__func__, "Could not load test image: %s", cpl_error_get_message());
    muse_image_delete(image);
    return cpl_test_end(2);
  }

  /* keep an image with cosmics for a 2nd try */
  muse_image *image2 = muse_image_duplicate(image),
             *image3 = muse_image_new(); /* small image */
  image3->header = cpl_propertylist_duplicate(image->header);
  image3->data = cpl_image_extract(image->data, 225, 65, 314, 226); // 225, 65, 271, 172
  image3->dq = cpl_image_extract(image->dq, 225, 65, 314, 226);
  image3->stat = cpl_image_extract(image->stat, 225, 65, 314, 226);

  /* use default values from muse_wavecal */
  cpl_errorstate state = cpl_errorstate_get();
  int ncr = muse_cosmics_dcr(image, 15, 40, 2, 4.5);
  cpl_test(ncr > 0);
  if (ncr > 0) {
    cpl_msg_info(__func__, "Found %d pixels affected by cosmic rays", ncr);

    /* just for display, replace all affected pixels with NAN */
    float *data = cpl_image_get_data_float(image->data);
    int *dq = cpl_image_get_data_int(image->dq);
    int nx = cpl_image_get_size_x(image->data),
        ny = cpl_image_get_size_y(image->data);
    int i;
    for (i = 0; i < nx; i++) {
      int j;
      for (j = 0; j < ny; j++) {
        if (dq[i + j*nx] & EURO3D_COSMICRAY) {
          data[i + j*nx] = NAN;
        }
      } /* for j */
    } /* for i */
#if 0
    muse_image_save(image, "cosmics_dcr.fits");
#endif
  }
  muse_image_delete(image);

  /* try again, to trigger all those cases with debug output */
  setenv("MUSE_DEBUG_DCR", "3", 1);
  int ncr2 = muse_cosmics_dcr(image2, 15, 40, 2, 4.5);
  cpl_test_eq(ncr, ncr2); /* should find the same number */
  unsetenv("MUSE_DEBUG_DCR");
  muse_image_delete(image2);

  /* add another case of a very small image, for the case of debug > 3 */
  setenv("MUSE_DEBUG_DCR", "5", 1);
  int ncr3 = muse_cosmics_dcr(image3, 15, 40, 1, 5.);
  cpl_test_eq(ncr3, 37); /* I see 3 CRs and count 37 pixels in that region */
#if 0
  muse_image_save(image3, "cosmics_dcr_im3.fits");
#endif
  unsetenv("MUSE_DEBUG_DCR");
  cpl_test(cpl_errorstate_is_equal(state));


  /* failure cases */
  ncr3 = muse_cosmics_dcr(NULL, 15, 5, 1, 5.);
  cpl_test_error(CPL_ERROR_NULL_INPUT);
  cpl_test_eq(ncr3, -1);
  ncr3 = muse_cosmics_dcr(image3, 15, 5, 1, -0.1);
  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
  cpl_test_eq(ncr3, -2);
  ncr3 = muse_cosmics_dcr(image3, 15, 5, 0, 5.);
  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
  cpl_test_eq(ncr3, -3);
  ncr3 = muse_cosmics_dcr(image3, cpl_image_get_size_x(image3->data) + 1,
                          5, 1, 5.);
  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
  cpl_test_eq(ncr3, -4);
  ncr3 = muse_cosmics_dcr(image3, 15, cpl_image_get_size_y(image3->data) + 1,
                          1, 5.);
  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
  cpl_test_eq(ncr3, -5);
  /* test with a small box, should trigger the warning, also     *
   * fill part of the image with NANs to simulate no good pixels */
  cpl_image_fill_window(image3->data, 1, 1, 16, 6, NAN);
  setenv("MUSE_DEBUG_DCR", "1", 1);
  ncr3 = muse_cosmics_dcr(image3, 15, 5, 2, 5.);
  unsetenv("MUSE_DEBUG_DCR");
  cpl_test_zero(ncr3); /*  image already treated, no more pixels found! */
  muse_image_delete(image3);

  return cpl_test_end(0);
}
