/* -*- 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) 2015 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.
 */

#include <muse.h>
#include <string.h>

/*----------------------------------------------------------------------------*/
/**
 * @defgroup tools_musegeosmooth            Tool muse_geo_smooth
 *
 * <b>muse_geo_smooth</b>: Fix the contents of a MUSE geometry table.
 *
 * Smooth the table by using linear fits within each slicer stack of each IFU.
 *
 * <b>Command line arguments:</b>
 *   - <tt>-s sigma</tt> (optional, default is 3.)\n
 *     rejection sigma level
 *   - <tt>-q</tt> (optional)\n
 *     is given, also run the QC routine on the smoothed table
 *   - <tt><b>GEOMETRY_TABLE</b></tt>\n
 *     the filename of the input geometry table
 *   - <tt><b>FIXED_TABLE</b></tt>\n
 *     the filename of the fixed output table
 *
 * <b>Return values:</b>
 *   - <tt> 0</tt>\n   Success
 *   - <tt> 1</tt>\n   no or wrong input or output filename given
 *   - <tt> 2</tt>\n   argument <tt>-s</tt> without value
 *   - <tt> 9</tt>\n   unknown option given
 *   - <tt>10</tt>\n   geometry table could not be loaded from file
 *   - <tt>50</tt>\n   unknown error
 */
/*----------------------------------------------------------------------------*/

/**@{*/

#define PRINT_USAGE(rc)                                                        \
  fprintf(stderr, "Usage: %s [ -s sigma ] [ -q ] GEOMETRY_TABLE FIXED_TABLE\n",\
          argv[0]);                                                            \
  cpl_end(); return (rc);

int main(int argc, char **argv)
{
  cpl_init(CPL_INIT_DEFAULT);
  muse_processing_recipeinfo(NULL);
  cpl_errorstate state = cpl_errorstate_get();

  if (argc <= 2) {
    /* filename is needed at least */
    PRINT_USAGE(1);
  }

  /* argument processing */
  char *tiname = NULL, /* input table */
       *toname = NULL; /* output table */
  double sigma = 3.; /* 3-sigma level rejection by default */
  cpl_boolean qc = CPL_FALSE;
  int i;
  for (i = 1; i < argc; i++) {
    if (strncmp(argv[i], "-s", 3) == 0) {
      i++; /* skip to next arg (sigma level value) */
      if (i < argc) {
        sigma = atof(argv[i]);
      } else {
        PRINT_USAGE(2);
      }
    } else if (strncmp(argv[i], "-q", 3) == 0) {
      qc = CPL_TRUE;
    } else if (strncmp(argv[i], "-", 1) == 0) { /* unallowed options */
      PRINT_USAGE(9);
    } else {
      if (tiname && toname) {
        break; /* we have the required names, skip the rest */
      }
      if (!tiname) {
        tiname = argv[i]; /* set the name for the input table */
      } else {
        toname = argv[i]; /* set the name for the output table */
      }
    }
  } /* for i (all arguments) */
  if (!tiname || !toname) {
    PRINT_USAGE(1);
  }
  cpl_msg_set_level(CPL_MSG_DEBUG);

  muse_geo_table *gt = muse_geo_table_new(1, 1.);
  cpl_table_delete(gt->table);
  gt->table = cpl_table_load(tiname, 1, 1);
  if (!gt->table) {
    muse_geo_table_delete(gt);
    PRINT_USAGE(10);
  }

  /* do the correction */
  cpl_propertylist *pheader = cpl_propertylist_load(tiname, 0);
  cpl_error_code rc = muse_geo_correct_slices(gt, pheader, sigma);
  if (qc) {
    muse_geo_qc_global(gt, pheader);
  }
  cpl_table_save(gt->table, pheader, NULL, toname, CPL_IO_CREATE);
  cpl_propertylist_delete(pheader);
  muse_geo_table_delete(gt);

  if (rc != CPL_ERROR_NONE) {
    cpl_msg_error(__func__, "Fixing the table failed: %s",
                  cpl_error_get_message());
  } else if (!cpl_errorstate_is_equal(state)) {
    cpl_msg_error(__func__, "An error occurred, unrelated to fixing the table: %s",
                  cpl_error_get_message());
    rc = 50;
  }
  cpl_memory_dump();
  cpl_end();
  return rc;
}

/**@}*/
