/*
 * This file is part of the KMOS Library
 * Copyright (C) 2007-2008 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 St, Fifth Floor, Boston, MA  02110-1301 USA
 */

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

#include <string.h>

#include "kmo_priv_functions.h"
#include "kmo_utils.h"
#include "kmo_dfs.h"
#include "kmo_cpl_extensions.h"
#include "kmo_debug.h"

/**
    @defgroup kmo_priv_functions_test   kmo_priv_functions unit tests

    @{
*/

void kmo_test_verbose_off();
void kmo_test_verbose_on();
void kmo_test_fill_vector(cpl_vector *vec, float seed, float offset);

/**
    @brief   test for kmo_create_lambda_vec
*/
void test_kmo_create_lambda_vec(void)
{
    float       tol  = 0.01;
    cpl_vector  *vec = NULL;

    /* --- invalid tests --- */
    kmo_test_verbose_off();
    cpl_test_null(vec = kmo_create_lambda_vec(0, -1, -1, -1));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    /* --- valid tests --- */
    cpl_test_nonnull(vec = kmo_create_lambda_vec(1, -1, -1, -1));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(vec), 1);
    cpl_test_eq(cpl_vector_get(vec, 0), -3);
    cpl_vector_delete(vec);

    cpl_test_nonnull(vec = kmo_create_lambda_vec(100, 1, 0.8, 0.00001));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(vec), 100);
    cpl_test_abs(cpl_vector_get_mean(vec), 0.800495, tol);
    cpl_test_abs(cpl_vector_get(vec, 0), 0.8, tol);
    cpl_vector_delete(vec);
}

/**
    @brief   test for kmo_is_in_range()
*/
void test_kmo_is_in_range(void)
{
    cpl_vector  *ranges = NULL,
                *lambda = NULL;

    /* --- invalid tests --- */
    kmo_test_verbose_off();
    cpl_test_eq(0, kmo_is_in_range(NULL, NULL, -1));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    ranges = cpl_vector_new(1);
    cpl_test_eq(0, kmo_is_in_range(ranges, NULL, -1));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    lambda = cpl_vector_new(100);
    cpl_test_eq(0, kmo_is_in_range(ranges, lambda, -1));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_eq(0, kmo_is_in_range(ranges, lambda, 10));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_vector_delete(ranges);
    kmo_test_verbose_on();

    /* --- valid tests --- */
    ranges = cpl_vector_new(4);
    cpl_vector_set(ranges, 0, 0.9);
    cpl_vector_set(ranges, 1, 1.0);
    cpl_vector_set(ranges, 2, 1.1);
    cpl_vector_set(ranges, 3, 1.6);
    kmo_test_fill_vector(lambda, 0.8, 0.01);
    cpl_test_eq(0, kmo_is_in_range(ranges, lambda, 1));
    cpl_test_eq(1, kmo_is_in_range(ranges, lambda, 12));
    cpl_test_eq(0, kmo_is_in_range(ranges, lambda, 28));
    cpl_test_eq(1, kmo_is_in_range(ranges, lambda, 32));
    cpl_test_eq(0, kmo_is_in_range(ranges, lambda, 90));
    cpl_test_error(CPL_ERROR_NONE);

    cpl_vector_delete(ranges);
    ranges = cpl_vector_new(2);
    cpl_vector_set(ranges, 0, 2.0);
    cpl_vector_set(ranges, 1, 2.1);
    cpl_test_eq(0, kmo_is_in_range(ranges, lambda, 0));
    cpl_test_eq(0, kmo_is_in_range(ranges, lambda, 99));

    cpl_vector_delete(ranges);
    cpl_vector_delete(lambda);
    cpl_test_error(CPL_ERROR_NONE);
}

/**
    @brief   test for kmo_is_in_range()
*/
void test_kmo_identify_slices(void)
{
    cpl_vector  *slices = NULL,
                *ranges = NULL;

    /* --- invalid tests --- */
//     kmo_test_verbose_off();
//     kmo_test_verbose_on();

    /* --- valid tests --- */
    cpl_test_nonnull(slices = kmo_identify_slices(NULL, 1, 0.8, 0.001, 10));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(slices), 10);
    cpl_test_eq(cpl_vector_get_mean(slices), 1.0);
    cpl_vector_delete(slices);

    ranges = cpl_vector_new(2);
    cpl_vector_set(ranges, 0, 0.805);
    cpl_vector_set(ranges, 1, 0.809);
    cpl_test_nonnull(slices = kmo_identify_slices(ranges, 1, 0.8, 0.001, 10));
    cpl_test_eq(cpl_vector_get_size(slices), 10);
    cpl_test_eq(cpl_vector_get_mean(slices), 0.5);

    cpl_vector_delete(slices);
    cpl_vector_delete(ranges);
    cpl_test_error(CPL_ERROR_NONE);
}

/**
    @brief   test for kmo_is_in_range()
*/
void test_kmo_identify_ranges(void)
{
    float       tol     = 0.01;
    cpl_vector  *vec    = NULL;

    cpl_test_null(vec = kmo_identify_ranges(""));
    cpl_test_error(CPL_ERROR_NONE);

    cpl_test_nonnull(vec = kmo_identify_ranges("1.1,2.2"));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(vec), 2);
    cpl_test_abs(cpl_vector_get(vec, 0), 1.1, tol);
    cpl_test_abs(cpl_vector_get(vec, 1), 2.2, tol);
    cpl_vector_delete(vec); vec = NULL;

    cpl_test_nonnull(vec = kmo_identify_ranges("1.1,2.2;3.3,4.4;5.5,6.6"));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(vec), 6);
    cpl_test_abs(cpl_vector_get(vec, 0), 1.1, tol);
    cpl_test_abs(cpl_vector_get(vec, 1), 2.2, tol);
    cpl_test_abs(cpl_vector_get(vec, 2), 3.3, tol);
    cpl_test_abs(cpl_vector_get(vec, 3), 4.4, tol);
    cpl_test_abs(cpl_vector_get(vec, 4), 5.5, tol);
    cpl_test_abs(cpl_vector_get(vec, 5), 6.6, tol);
    cpl_vector_delete(vec); vec = NULL;

    cpl_test_nonnull(vec = kmo_identify_ranges("1,2"));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(vec), 2);
    cpl_test_abs(cpl_vector_get(vec, 0), 1.0, tol);
    cpl_test_abs(cpl_vector_get(vec, 1), 2.0, tol);
    cpl_vector_delete(vec); vec = NULL;

    kmo_test_verbose_off();
    cpl_test_null(vec = kmo_identify_ranges("1"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(vec = kmo_identify_ranges("1,2;3"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(vec = kmo_identify_ranges("1-2:3-4"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(vec = kmo_identify_ranges("1;3,4"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(vec = kmo_identify_ranges("1-2;3-4"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(vec = kmo_identify_ranges("1.1;3.3"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_test_error(CPL_ERROR_NONE);
}

/**
    @brief   test for kmo_identify_values()
*/
void test_kmo_identify_values(void)
{
    float       tol     = 0.01;
    cpl_vector  *vec    = NULL;

    cpl_test_null(vec = kmo_identify_values(""));
    cpl_test_error(CPL_ERROR_NONE);

    cpl_test_nonnull(vec = kmo_identify_values("1"));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(vec), 1);
    cpl_test_abs(cpl_vector_get(vec, 0), 1, tol);
    cpl_vector_delete(vec); vec = NULL;

    cpl_test_nonnull(vec = kmo_identify_values("1.1"));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(vec), 1);
    cpl_test_abs(cpl_vector_get(vec, 0), 1.1, tol);
    cpl_vector_delete(vec); vec = NULL;

    cpl_test_nonnull(vec = kmo_identify_values("1.1;3.3"));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(vec), 2);
    cpl_test_abs(cpl_vector_get(vec, 0), 1.1, tol);
    cpl_test_abs(cpl_vector_get(vec, 1), 3.3, tol);
    cpl_vector_delete(vec); vec = NULL;

    cpl_test_nonnull(vec = kmo_identify_values("1.1;2.2;3.3;4.4;5.5;6.6"));
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_eq(cpl_vector_get_size(vec), 6);
    cpl_test_abs(cpl_vector_get(vec, 0), 1.1, tol);
    cpl_test_abs(cpl_vector_get(vec, 1), 2.2, tol);
    cpl_test_abs(cpl_vector_get(vec, 2), 3.3, tol);
    cpl_test_abs(cpl_vector_get(vec, 3), 4.4, tol);
    cpl_test_abs(cpl_vector_get(vec, 4), 5.5, tol);
    cpl_test_abs(cpl_vector_get(vec, 5), 6.6, tol);
    cpl_vector_delete(vec); vec = NULL;

    kmo_test_verbose_off();
    cpl_test_null(vec = kmo_identify_values("1,2;3"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(vec = kmo_identify_values("1-2:3-4"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(vec = kmo_identify_values("1;3,4"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(vec = kmo_identify_values("1.1,2.2;3.3,4.4;5.5,6.6"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

//    cpl_test_error(CPL_ERROR_NONE);
}

/**
 * @brief   test for kmo_image_get_stdev_median()
 */
void test_kmo_image_get_stdev_median(void)
{
    cpl_image  *img    = NULL;

    float      tol     = 0.01;

    /* --- invalid tests --- */
    kmo_test_verbose_off();
    cpl_test_eq(0.0, kmo_image_get_stdev_median(NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    /* --- valid tests --- */
    img = cpl_image_new(3, 3, CPL_TYPE_FLOAT);
    cpl_image_set(img, 1, 1, 0.);
    cpl_image_set(img, 1, 2, 1.);
    cpl_image_set(img, 1, 3, 100.);
    cpl_image_set(img, 2, 1, -10.);
    cpl_image_set(img, 2, 2, 0.5);
    cpl_image_set(img, 2, 3, 0.5);
    cpl_image_set(img, 3, 1, 0.5);
    cpl_image_set(img, 3, 2, 1.5);
    cpl_image_set(img, 3, 3, 1.5);

    cpl_test_abs(kmo_image_get_stdev_median(img), 35.3783, tol);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_image_reject(img, 2, 3);
    cpl_image_reject(img, 3, 3);

    cpl_test_abs(kmo_image_get_stdev_median(img), 40.8493, tol);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_image_delete(img);
}

/**
 * @brief   test for kmos_combine_pars_create()
 */
void test_kmos_combine_pars_create(void)
{
    cpl_test_eq(-1, kmos_combine_pars_create(NULL, NULL, NULL, -1));

    cpl_parameterlist *pl = cpl_parameterlist_new();
    cpl_test_eq(-1, kmos_combine_pars_create(pl, NULL, NULL, -1));
    cpl_test_eq(0, cpl_parameterlist_get_size(pl));

    cpl_test_eq(0, kmos_combine_pars_create(pl, "recipeA", NULL, -1));
    cpl_test_eq(0, cpl_parameterlist_get_size(pl));
    cpl_parameterlist_delete(pl);

    pl = cpl_parameterlist_new();
    cpl_test_eq(0, kmos_combine_pars_create(pl, "recipeA", NULL, FALSE));
    cpl_test_eq(6, cpl_parameterlist_get_size(pl));
    cpl_parameterlist_delete(pl);

    pl = cpl_parameterlist_new();
    cpl_test_eq(0, kmos_combine_pars_create(pl, "recipeA", "ksigma", TRUE));
    cpl_test_eq(3, cpl_parameterlist_get_size(pl));
    cpl_parameterlist_delete(pl);

    cpl_test_error(CPL_ERROR_NONE);
}

/**
 * @brief   test for kmos_band_pars_create()
 */
void test_kmos_band_pars_create(void)
{
    kmos_band_pars_create(NULL, NULL);

    cpl_parameterlist *pl = cpl_parameterlist_new();
    kmos_band_pars_create(pl, NULL);
    cpl_test_eq(0, cpl_parameterlist_get_size(pl));

    kmos_band_pars_create(pl, "recipeA");
    cpl_test_eq(1, cpl_parameterlist_get_size(pl));

    cpl_test_error(CPL_ERROR_NONE);

    cpl_parameterlist_delete(pl);
}

/**
 * @brief   test for kmos_combine_pars_load()
 */
void test_kmos_combine_pars_load(void)
{
    kmo_test_verbose_off();
    kmos_combine_pars_load(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_parameterlist *pl = NULL;
    kmos_combine_pars_load(pl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmos_combine_pars_load(pl, "recipeA", NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    const char *cmethod = NULL;
    kmos_combine_pars_load(pl, "kmos.recipeA", &cmethod, NULL, NULL, NULL, NULL, NULL, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    pl = cpl_parameterlist_new();
    kmos_combine_pars_load(pl, "kmos.recipeA", &cmethod, NULL, NULL, NULL, NULL, NULL, FALSE);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_test_eq(0, kmos_combine_pars_create(pl, "recipeA", "ksigma", TRUE));

    double cpos_rej = -1, cneg_rej = -1;
    int citer = -1, cmin = -1, cmax = -1;
    kmos_combine_pars_load(pl, "recipeA", NULL, &cpos_rej, &cneg_rej,
                          &citer, NULL, NULL, FALSE);

    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_abs(3, cpos_rej, 0.01);
    cpl_test_abs(3, cneg_rej, 0.01);
    cpl_test_eq(3, citer);
    cpl_test_eq(-1, cmin);
    cpl_test_eq(-1, cmax);
    cpl_parameterlist_delete(pl);

    pl = cpl_parameterlist_new();
    kmos_combine_pars_load(pl, "kmos.recipeA", &cmethod, NULL, NULL, NULL, NULL, NULL, FALSE);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_test_eq(0, kmos_combine_pars_create(pl, "recipeA", "min_max", TRUE));
    cpos_rej =-1, cneg_rej = -1;
    citer = -1, cmin = -1, cmax = -1;
    kmos_combine_pars_load(pl, "recipeA", NULL, NULL, NULL,
                          NULL, &cmin, &cmax, FALSE);
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_abs(-1, cpos_rej, 0.01);
    cpl_test_abs(-1, cneg_rej, 0.01);
    cpl_test_eq(-1, citer);
    cpl_test_eq(1, cmin);
    cpl_test_eq(1, cmax);
    cpl_parameterlist_delete(pl);

    cpl_test_error(CPL_ERROR_NONE);
}

/**
 * @brief   test for kmos_band_pars_load()
 */
void test_kmos_band_pars_load(void)
{
    kmo_test_verbose_off();
    kmos_band_pars_load(NULL, NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_parameterlist *pl = NULL;
    kmos_band_pars_load(pl, NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmos_band_pars_load(pl, "recipeA");
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    pl = cpl_parameterlist_new();
    kmos_band_pars_create(pl, "recipeA");
    kmos_band_pars_load(pl, "recipeA");
    cpl_test_error(CPL_ERROR_NONE);

    cpl_parameterlist_delete(pl);
}

/**
 * @brief   test for kmo_check_frameset_setup()
 */
void test_kmo_check_frameset_setup(void)
{
    kmo_test_verbose_off();
    kmo_check_frameset_setup(NULL, NULL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_frameset *fs = cpl_frameset_new();
    kmo_check_frameset_setup(fs, NULL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_check_frameset_setup(fs, FLAT_ON, 0, 0, 0);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_frame *fr = cpl_frame_new();
    cpl_frame_set_tag(fr, FLAT_ON);
    char *my_path = cpl_sprintf("%s/ref_data/flat_on1.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr, my_path);
    cpl_frameset_insert(fs, fr);
    cpl_free(my_path);
    kmo_check_frameset_setup(fs, FLAT_ON, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_check_frameset_setup(fs, FLAT_ON, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_check_frameset_setup(fs, FLAT_ON, 1, 0, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_check_frameset_setup(fs, FLAT_ON, 1, 1, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_check_frameset_setup(fs, FLAT_ON, 1, 1, 1);
    cpl_test_error(CPL_ERROR_NONE);

    fr = cpl_frame_new();
    cpl_frame_set_tag(fr, FLAT_ON);
    my_path = cpl_sprintf("%s/ref_data/flat_on2.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr, my_path);
    cpl_frameset_insert(fs, fr);
    cpl_free(my_path);
    kmo_check_frameset_setup(fs, FLAT_ON, 1, 1, 1);
    cpl_test_error(CPL_ERROR_NONE);

    fr = cpl_frame_new();
    cpl_frame_set_tag(fr, DARK);
    my_path = cpl_sprintf("%s/ref_data/dark1.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr, my_path);
    cpl_free(my_path);
    cpl_frameset_insert(fs, fr);
    kmo_check_frameset_setup(fs, FLAT_ON, 1, 1, 1);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_test_verbose_off();
    fr = cpl_frame_new();
    cpl_frame_set_tag(fr, FLAT_ON);
    my_path = cpl_sprintf("%s/ref_data/flat_on3.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr, my_path);
    cpl_free(my_path);
    cpl_frameset_insert(fs, fr);
    kmo_check_frameset_setup(fs, FLAT_ON, 1, 1, 1);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_frameset_delete(fs);
    cpl_test_error(CPL_ERROR_NONE);
}

/**
 * @brief   test for kmo_check_frame_setup()
 */
void test_kmo_check_frame_setup(void)
{
    kmo_test_verbose_off();
    kmo_check_frame_setup(NULL, NULL, NULL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_frameset *fs = cpl_frameset_new();
    kmo_check_frame_setup(fs, NULL, NULL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_check_frame_setup(fs, FLAT_ON, NULL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_check_frame_setup(fs, FLAT_ON, FLAT_ON, 0, 0, 0);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_frame *fr = cpl_frame_new();
    cpl_frame_set_tag(fr, FLAT_ON);
    char *my_path = cpl_sprintf("%s/ref_data/flat_on1.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr, my_path);
    cpl_free(my_path);
    cpl_frameset_insert(fs, fr);
    fr = cpl_frame_new();
    cpl_frame_set_tag(fr, XCAL);
    my_path = cpl_sprintf("%s/ref_data/flat_on2.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr, my_path);
    cpl_free(my_path);
    cpl_frameset_insert(fs, fr);
    kmo_check_frame_setup(fs, FLAT_ON, XCAL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_check_frame_setup(fs, FLAT_ON, XCAL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_check_frame_setup(fs, FLAT_ON, XCAL, 1, 0, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_check_frame_setup(fs, FLAT_ON, XCAL, 1, 1, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_check_frame_setup(fs, FLAT_ON, XCAL, 1, 1, 1);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_test_verbose_off();
    fr = cpl_frame_new();
    cpl_frame_set_tag(fr, FLAT_OFF);
    my_path = cpl_sprintf("%s/ref_data/dark1.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr, my_path);
    cpl_free(my_path);
    cpl_frameset_insert(fs, fr);
    kmo_check_frame_setup(fs, FLAT_ON, FLAT_OFF, 1, 1, 1);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    fr = cpl_frame_new();
    cpl_frame_set_tag(fr, YCAL);
    my_path = cpl_sprintf("%s/ref_data/flat_on3.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr, my_path);
    cpl_free(my_path);
    cpl_frameset_insert(fs, fr);
    kmo_check_frame_setup(fs, FLAT_ON, YCAL, 1, 1, 1);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_frameset_delete(fs);
    cpl_test_error(CPL_ERROR_NONE);
}

/**
 * @brief   test for kmo_priv_compare_frameset_setup()
 */
void test_kmo_priv_compare_frameset_setup(void)
{
    cpl_frame *fr1 = cpl_frame_new();
    cpl_frame_set_tag(fr1, FLAT_ON);
    char *my_path = cpl_sprintf("%s/ref_data/flat_on1.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr1, my_path);
    cpl_free(my_path);
    cpl_frame *fr2 = cpl_frame_new();
    cpl_frame_set_tag(fr2, XCAL);
    my_path = cpl_sprintf("%s/ref_data/flat_on2.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr2, my_path);
    cpl_free(my_path);
    cpl_frame *fr3 = cpl_frame_new();
    cpl_frame_set_tag(fr3, FLAT_ON);
    my_path = cpl_sprintf("%s/ref_data/flat_on3.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr3, my_path);
    cpl_free(my_path);
    cpl_frame *fr4 = cpl_frame_new();
    cpl_frame_set_tag(fr4, FLAT_OFF);
    my_path = cpl_sprintf("%s/ref_data/dark1.fits", getenv("srcdir"));
    cpl_frame_set_filename(fr4, my_path);
    cpl_free(my_path);

    kmo_test_verbose_off();
    kmo_priv_compare_frame_setup(NULL, NULL, NULL, NULL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_priv_compare_frame_setup(fr1, NULL, NULL, NULL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_priv_compare_frame_setup(fr1, fr2, NULL, NULL, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_test_verbose_on();

    kmo_priv_compare_frame_setup(fr1, fr2, FLAT_ON, FLAT_ON, 0, 0, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_priv_compare_frame_setup(fr1, fr2, FLAT_ON, FLAT_ON, 1, 0, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_priv_compare_frame_setup(fr1, fr2, FLAT_ON, FLAT_ON, 1, 1, 0);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_priv_compare_frame_setup(fr1, fr2, FLAT_ON, FLAT_ON, 1, 1, 1);
    cpl_test_error(CPL_ERROR_NONE);

    kmo_test_verbose_off();
    kmo_priv_compare_frame_setup(fr1, fr3, FLAT_ON, FLAT_ON, 1, 1, 1);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    kmo_priv_compare_frame_setup(fr1, fr4, FLAT_ON, FLAT_OFF, 1, 1, 1);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    kmo_priv_compare_frame_setup(fr1, fr4, FLAT_ON, FLAT_ON, 1, 1, 1);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    kmo_priv_compare_frame_setup(fr1, fr3, FLAT_ON, XCAL, 1, 1, 1);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_frame_delete(fr1);
    cpl_frame_delete(fr2);
    cpl_frame_delete(fr3);
    cpl_frame_delete(fr4);
    cpl_test_error(CPL_ERROR_NONE);
}

/**
    @brief   Test of helper functions needed in several recipes
*/
int main(void)
{
    cpl_test_init("<usd-help@eso.org>", CPL_MSG_WARNING);

    test_kmo_create_lambda_vec();
    test_kmo_is_in_range();
    test_kmo_identify_slices();
    test_kmo_identify_ranges();
    test_kmo_identify_values();
    test_kmo_image_get_stdev_median();
    test_kmos_combine_pars_create();
    test_kmos_band_pars_create();
    /* test_kmos_combine_pars_load(); */
    test_kmos_band_pars_load();
    /* test_kmo_check_frameset_setup(); */
    /* test_kmo_check_frame_setup(); */
    /* test_kmo_priv_compare_frameset_setup(); */

    return cpl_test_end(0);
}

/** @} */
