/*
 * 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 "kmclipm_functions.h"
#include "kmclipm_vector.h"
#include "kmclipm_constants.h"

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

/**
    @defgroup kmo_dfs_test   kmo_dfs unit tests

    @{
 */

void kmo_test_verbose_off();
void kmo_test_verbose_on();
cpl_frame* kmo_test_frame_new(const char *filename, const char *tag, cpl_frame_group group);
void kmo_test_fill_vector(cpl_vector *vec, float seed, float offset);
void kmo_test_fill_image(cpl_image *img, float seed, float offset);
void kmo_test_fill_cube(cpl_imagelist *cube, float seed, float offset);
void kmo_test_alloc_cube(cpl_imagelist *cube, int x, int y, int z);

/**
 * @brief   test strlower
 */
void test_strlower()
{
    char *s = cpl_sprintf("%s", "GAGA");
    cpl_test_nonnull(strlower(s));
    cpl_test_eq_string(s, "gaga");
    cpl_free(s); s = NULL;
}

/**
 * @brief   test kmo_extname_extractor
 */
void test_kmo_extname_extractor()
{
    char *s = cpl_sprintf("%s", "DET.1.DATA");
    enum kmo_frame_type type = illegal_frame;
    int id = 0;
    char content[64];

    kmo_extname_extractor(s, &type, &id, content);
    cpl_test_eq(type, detector_frame);
    cpl_test_eq(id, 1);
    cpl_test_eq_string(content, "DATA");
    cpl_free(s); s = NULL;
    cpl_test_error(CPL_ERROR_NONE);
}

/**
 * @brief   test kmo_extname_creator
 */
void test_kmo_extname_creator()
{
    char *s = kmo_extname_creator(detector_frame, 2, EXT_NOISE);

    cpl_test_eq_string("DET.2.NOISE", s);
    cpl_free(s);
    cpl_test_error(CPL_ERROR_NONE);
}

/**
 * @brief   test kmo_get_index_from_ocs_name
 */
void test_kmo_get_index_from_ocs_name()
{
    cpl_frame  *fr = NULL;
    cpl_vector *v  = NULL;

    kmo_test_verbose_off();

    cpl_test_eq(-1, kmo_get_index_from_ocs_name(NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    fr = cpl_frame_new();
    cpl_test_eq(-1, kmo_get_index_from_ocs_name(fr, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_frame_delete(fr);

    fr = kmo_test_frame_new("dada_vec.fits", "", CPL_FRAME_GROUP_RAW);
    cpl_test_eq(-1, kmo_get_index_from_ocs_name(fr, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_frame_delete(fr);

    kmo_test_verbose_on();


    v = cpl_vector_new(3);
    cpl_vector_fill(v, 0);

    // test: frame is a processed one (has CATG keyword)
    cpl_propertylist *pl = cpl_propertylist_new();
    cpl_propertylist_update_string(pl, CPL_DFS_PRO_CATG, "GAGA");
    cpl_propertylist_save(pl, "ttt.fits", CPL_IO_CREATE);
    cpl_propertylist_update_string(pl, "EXTNAME", "DET.2.DATA");
    cpl_propertylist_update_string(pl, "ESO OCS ARM2 NAME", "GAGA");
    cpl_propertylist_erase(pl, CPL_DFS_PRO_CATG);
    cpl_vector_save(v, "ttt.fits", CPL_BPP_IEEE_DOUBLE, pl, CPL_IO_EXTEND);
    fr = kmo_test_frame_new("ttt.fits", "", CPL_FRAME_GROUP_CALIB);
    cpl_test_eq(2, kmo_get_index_from_ocs_name(fr, "GAGA"));
    cpl_frame_delete(fr);
    cpl_propertylist_delete(pl);

    // test: frame is a raw one (doesn't have CATG keyword)
    pl = cpl_propertylist_new();
    cpl_propertylist_update_string(pl, "ESO OCS ARM1 NAME", "DADA");
    cpl_propertylist_update_string(pl, "ESO OCS ARM2 NAME", "DADA");
    cpl_propertylist_update_string(pl, "ESO OCS ARM3 NAME", "GAGA");
    cpl_propertylist_save(pl, "ttt.fits", CPL_IO_CREATE);
    cpl_propertylist_delete(pl);
    pl = cpl_propertylist_new();
    cpl_vector_save(v, "ttt.fits", CPL_BPP_IEEE_DOUBLE, pl, CPL_IO_EXTEND);
    fr = kmo_test_frame_new("ttt.fits", "", CPL_FRAME_GROUP_RAW);
    cpl_test_eq(3, kmo_get_index_from_ocs_name(fr, "GAGA"));
    cpl_frame_delete(fr);
    cpl_propertylist_delete(pl);

    cpl_vector_delete(v);

    cpl_test_error(CPL_ERROR_NONE);
}

/**
 * @brief   test kmo_update_sub_keywords
 */
void test_kmo_update_sub_keywords()
{
    cpl_propertylist *pl = cpl_propertylist_new();

    kmo_test_verbose_off();
    cpl_test_eq(CPL_ERROR_NULL_INPUT,
                kmo_update_sub_keywords(NULL, TRUE, FALSE, detector_frame, 2));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_test_eq(CPL_ERROR_ILLEGAL_INPUT,
                kmo_update_sub_keywords(pl, TRUE, FALSE, 25, 2));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_eq(CPL_ERROR_ILLEGAL_INPUT,
                kmo_update_sub_keywords(pl, -1, FALSE, detector_frame, 2));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_test_eq(CPL_ERROR_NONE,
                kmo_update_sub_keywords(pl, TRUE, FALSE, detector_frame, 2));

    cpl_propertylist_delete(pl);
}

/**
 * @brief   test kmo_dfs_load_primary_header
 */
void test_kmo_dfs_load_primary_header()
{
    cpl_propertylist    *pl         = NULL;
    cpl_frameset        *fs         = cpl_frameset_new();
    cpl_frame           *fr         = NULL;
    char *my_path = cpl_sprintf("%s/ref_data/KMOS_dummy.fits", getenv("srcdir"));
    fr = kmo_test_frame_new(my_path, "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);

    kmo_test_verbose_off();
    cpl_test_null(pl = kmo_dfs_load_primary_header(NULL, "0"));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_null(pl = kmo_dfs_load_primary_header(fs, NULL));
    cpl_test_null(pl = kmo_dfs_load_primary_header(fs, "1"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_test_null(pl = kmo_dfs_load_primary_header(fs, "-1"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_test_nonnull(pl = kmo_dfs_load_primary_header(fs, "0"));
    cpl_test_eq_string("ESO", cpl_propertylist_get_string(pl, "ORIGIN"));

    cpl_propertylist_delete(pl);
    cpl_frameset_delete(fs);
    cpl_free(my_path);
}

/**
 * @brief   test kmo_dfs_load_sub_header
 */
void test_kmo_dfs_load_sub_header()
{
    cpl_propertylist    *pl         = NULL;
    cpl_frameset        *fs         = cpl_frameset_new();
    cpl_frame           *fr         = NULL;
    char *my_path = cpl_sprintf("%s/ref_data/KMOS_dummy.fits", getenv("srcdir"));
    fr = kmo_test_frame_new(my_path, "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);

    kmo_test_verbose_off();
    cpl_test_null(pl = kmo_dfs_load_sub_header(NULL, "0", 1, 0));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_null(pl = kmo_dfs_load_sub_header(fs, NULL, 1, 0));
    cpl_test_null(pl = kmo_dfs_load_sub_header(fs, "1", 1, 0));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_test_null(pl = kmo_dfs_load_sub_header(fs, "-1", 1, 0));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_test_null(pl = kmo_dfs_load_sub_header(fs, "0", -1, 0));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_test_null(pl = kmo_dfs_load_sub_header(fs, "0", 23, 0));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_test_nonnull(pl = kmo_dfs_load_sub_header(fs, "0", 1, 0));
    cpl_test_eq_string("CHIP1.INT1", cpl_propertylist_get_string(pl, EXTNAME));

    cpl_propertylist_delete(pl);
    cpl_frameset_delete(fs);
    cpl_free(my_path);
}

/**
 * @brief   test kmo_dfs_load_vector()
 */
void test_kmo_dfs_load_vector()
{
    cpl_frameset     *fs          = NULL;
    cpl_frame        *fr          = NULL;
    cpl_vector       *v           = cpl_vector_new(3);
    kmclipm_vector   *vec         = NULL,
                     *vec_loaded  = NULL;
    float            tol          = 0.01;

    kmo_test_fill_vector(v, 0.0, 1.0);
    vec = kmclipm_vector_create(v);

    kmo_test_verbose_off();

    cpl_test_null(vec_loaded = kmo_dfs_load_vector(NULL, NULL, -1, -1));
                  cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_frameset *fs_empty = cpl_frameset_new();
    cpl_test_null(vec_loaded = kmo_dfs_load_vector(fs_empty, NULL, -1, -1));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_test_null(vec_loaded = kmo_dfs_load_vector(fs_empty, "aga", -1, -1));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_test_null(vec_loaded = kmo_dfs_load_vector(fs_empty, "aga", 6, -1));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_test_null(vec_loaded = kmo_dfs_load_vector(fs_empty, "aga", 6, 1));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_frameset_delete(fs_empty);

    fs = cpl_frameset_new();
    fr = kmo_test_frame_new("aga_vec.fits",
                            "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);

    cpl_test_null(vec_loaded = kmo_dfs_load_vector(fs, "0", 2, 0));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_test_nonnull(vec_loaded = kmo_dfs_load_vector(fs, "0", 1, 0));

    kmclipm_vector_subtract(vec, vec_loaded);

    cpl_test_abs(kmclipm_vector_get_mean(vec), 0.0, tol);

    kmclipm_vector_delete(vec);
    kmclipm_vector_delete(vec_loaded);

    cpl_frameset_delete(fs);
}

/**
 * @brief   test kmo_dfs_load_image()
 */
void test_kmo_dfs_load_image()
{
    cpl_frameset     *fs          = NULL;
    cpl_frame        *fr          = NULL;
    cpl_image        *img         = cpl_image_new(2, 2, CPL_TYPE_FLOAT),
                     *img_loaded  = NULL;
    float            tol          = 0.01;

    kmo_test_fill_image(img, 0.0, 1.0);

    kmo_test_verbose_off();

    cpl_test_null(img_loaded = kmo_dfs_load_image(NULL, NULL, -1, -1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_frameset *fs_empty = cpl_frameset_new();

    cpl_test_null(img_loaded = kmo_dfs_load_image(fs_empty, NULL, -1, -1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image(fs_empty, "aga", -1, -1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image(fs_empty, "aga", 6, -1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image(fs_empty, "aga", 6, 1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    fs = cpl_frameset_new();
    fr = kmo_test_frame_new("aga_img.fits",
                            "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);

    kmo_test_verbose_on();

    cpl_test_nonnull(img_loaded = kmo_dfs_load_image(fs, "0", 1, 0, FALSE, NULL));

    cpl_image_subtract(img, img_loaded);

    cpl_test_abs(cpl_image_get_mean(img), 0.0, tol);

    cpl_image_delete(img);
    cpl_image_delete(img_loaded);
    cpl_frameset_delete(fs);
    cpl_frameset_delete(fs_empty);
}

/**
 * @brief   test kmo_dfs_load_image_window()
 */
void test_kmo_dfs_load_image_window()
{
    cpl_frameset     *fs          = NULL;
    cpl_frame        *fr          = NULL;
    cpl_image        *img         = cpl_image_new(2, 2, CPL_TYPE_FLOAT),
                     *img_loaded  = NULL;
    float            tol          = 0.01;

    kmo_test_fill_image(img, 0.0, 1.0);

    kmo_test_verbose_off();

    cpl_test_null(img_loaded = kmo_dfs_load_image_window(NULL, NULL, -1, -1,
                                                         -1, -1, -1, -1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_frameset *fs_empty = cpl_frameset_new();

    cpl_test_null(img_loaded = kmo_dfs_load_image_window(fs_empty, NULL, -1, -1,
                                                         -1, -1, -1, -1, FALSE, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image_window(fs_empty, "aga", -1, -1,
                                                         -1, -1, -1, -1, FALSE, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image_window(fs_empty, "aga", 6, -1,
                                                         -1, -1, -1, -1, FALSE, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image_window(fs_empty, "aga", 6, 1,
                                                         -1, -1, -1, -1, FALSE, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    fs = cpl_frameset_new();
    fr = kmo_test_frame_new("aga_img.fits",
                            "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);

    kmo_test_verbose_on();

    cpl_test_nonnull(img_loaded = kmo_dfs_load_image_window(fs, "0", 1, 0,
                                                            1, 1, 2, 2, FALSE, NULL));

    cpl_image_subtract(img, img_loaded);

    cpl_test_abs(cpl_image_get_mean(img), 0.0, tol);

    cpl_image_delete(img);
    cpl_image_delete(img_loaded);
    cpl_frameset_delete(fs);
    cpl_frameset_delete(fs_empty);
}

/**
 * @brief   test kmo_dfs_load_image_frame()
 */
void test_kmo_dfs_load_image_frame()
{
    cpl_frame        *fr          = NULL;
    cpl_image        *img         = cpl_image_new(2, 2, CPL_TYPE_FLOAT),
                     *img_loaded  = NULL;
    float            tol          = 0.01;

    kmo_test_fill_image(img, 0.0, 1.0);

    kmo_test_verbose_off();

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame(NULL, -1, -1, FALSE, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    fr = kmo_test_frame_new("aga_img.fits",
                            "", CPL_FRAME_GROUP_RAW);

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame(fr, -1, -1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame(fr, -1, -1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame(fr, 6, -1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame(fr, 6, 1, FALSE, NULL));
                  cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    kmo_test_verbose_on();

    cpl_test_nonnull(img_loaded = kmo_dfs_load_image_frame(fr, 1, 0, FALSE, NULL));

    cpl_image_subtract(img, img_loaded);

    cpl_test_abs(cpl_image_get_mean(img), 0.0, tol);

    cpl_image_delete(img);
    cpl_image_delete(img_loaded);
    cpl_frame_delete(fr);
}

/**
 * @brief   test kmo_dfs_load_image_frame_window()
 */
void test_kmo_dfs_load_image_frame_window()
{
    cpl_frame        *fr          = NULL;
    cpl_image        *img         = cpl_image_new(2, 2, CPL_TYPE_FLOAT),
                     *img_loaded  = NULL;
    float            tol          = 0.01;

    kmo_test_fill_image(img, 0.0, 1.0);

    kmo_test_verbose_off();

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame_window(NULL, -1, -1,
                                                               -1, -1, -1, -1,
                                                               FALSE, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    fr = kmo_test_frame_new("aga_img.fits",
                            "", CPL_FRAME_GROUP_RAW);

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame_window(fr, -1, -1,
                                                               -1, -1, -1, -1,
                                                               FALSE, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame_window(fr, -1, -1,
                                                               -1, -1, -1, -1,
                                                               FALSE, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame_window(fr, 6, -1,
                                                               -1, -1, -1, -1,
                                                               FALSE, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(img_loaded = kmo_dfs_load_image_frame_window(fr, 6, 1,
                                                               -1, -1, -1, -1,
                                                               FALSE, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    kmo_test_verbose_on();

    cpl_test_nonnull(img_loaded = kmo_dfs_load_image_frame_window(fr, 1, 0,
                                                                  1, 1, 2, 2,
                                                                  FALSE, NULL));

    cpl_image_subtract(img, img_loaded);

    cpl_test_abs(cpl_image_get_mean(img), 0.0, tol);

    cpl_image_delete(img);
    cpl_image_delete(img_loaded);
    cpl_frame_delete(fr);
}

/**
 * @brief   test kmo_dfs_load_cube()
 */
void test_kmo_dfs_load_cube()
{
    cpl_frameset     *fs          = NULL;
    cpl_frame        *fr          = NULL;
    cpl_imagelist    *cube        = cpl_imagelist_new(),
                      *cube_loaded = NULL;
    float            tol          = 0.01;

    kmo_test_alloc_cube(cube, 5, 5, 3);
    kmo_test_fill_cube(cube, 0.0, 1.0);

    kmo_test_verbose_off();

    cpl_test_null(cube_loaded = kmo_dfs_load_cube(NULL, NULL, -1, -1));
                  cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_frameset *fs_empty = cpl_frameset_new();

    cpl_test_null(cube_loaded = kmo_dfs_load_cube(fs_empty, NULL, -1, -1));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(cube_loaded = kmo_dfs_load_cube(fs_empty, "aga", -1, -1));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(cube_loaded = kmo_dfs_load_cube(fs_empty, "aga", 6, -1));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(cube_loaded = kmo_dfs_load_cube(fs_empty, "aga", 6, 1));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    fs = cpl_frameset_new();
    fr = kmo_test_frame_new("aga_cube.fits",
                            "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);

    cpl_test_nonnull(cube_loaded = kmo_dfs_load_cube(fs, "0", 1, 0));

    cpl_imagelist_subtract(cube, cube_loaded);
    cpl_image *ccc = cpl_imagelist_collapse_create(cube);

    cpl_test_abs(cpl_image_get_mean(ccc), 0.0, tol);

    cpl_imagelist_delete(cube);
    cpl_imagelist_delete(cube_loaded);
    cpl_image_delete(ccc);

    cpl_frameset_delete(fs);
    cpl_frameset_delete(fs_empty);
}

/**
 * @brief   test kmo_dfs_load_table()
 */
void test_kmo_dfs_load_table()
{
    kmo_test_verbose_off();
    cpl_test_null(kmo_dfs_load_table(NULL, NULL, -1, -1));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_frameset *fs = cpl_frameset_new();
    cpl_test_null(kmo_dfs_load_table(fs, NULL, -1, -1));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(kmo_dfs_load_table(fs, NULL, 1, -1));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_test_null(kmo_dfs_load_table(fs, NULL, 1, 0));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    cpl_frame *fr = kmo_test_frame_new("aga_tbl.fits", "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);
    cpl_test_null(kmo_dfs_load_table(fs, NULL, 1, 0));
    cpl_test_error(CPL_ERROR_NONE);

    cpl_frameset_delete(fs);
}

/**
 * @brief   test kmo_dfs_create_filename()
 */
void test_kmo_dfs_create_filename()
{
    char *s = NULL;
    kmo_test_verbose_off();
    cpl_test_null(kmo_dfs_create_filename(NULL, NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_null(kmo_dfs_create_filename("ggg", NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_null(kmo_dfs_create_filename("ggg", "ddd", NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();
    cpl_test_nonnull(s = kmo_dfs_create_filename("ggg", "ddd", "aaa"));
    cpl_test_eq_string("gggdddaaa.fits", s);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_free(s);
}

/**
 * @brief   test kmo_dfs_save_main_header()
 */
void test_kmo_dfs_save_main_header()
{
    cpl_propertylist    *pl         = NULL;
    cpl_frameset        *fs         = cpl_frameset_new();
    cpl_frame           *fr         = NULL;
    cpl_parameterlist   *parl       = cpl_parameterlist_new();

    kmo_test_verbose_off();
    cpl_test_eq(CPL_ERROR_NULL_INPUT,
        kmo_dfs_save_main_header(NULL, NULL, NULL, NULL, NULL, NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(CPL_ERROR_NULL_INPUT,
        kmo_dfs_save_main_header(fs, NULL, NULL, NULL, NULL, NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(CPL_ERROR_NULL_INPUT,
        kmo_dfs_save_main_header(fs, "aga", NULL, NULL, NULL, NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(CPL_ERROR_NULL_INPUT,
        kmo_dfs_save_main_header(fs, "aga", NULL, NULL, NULL, NULL, ""));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    char *my_path = cpl_sprintf("%s/ref_data/KMOS_dummy.fits", getenv("srcdir"));
    fr = kmo_test_frame_new(my_path, "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);

    cpl_test_eq(CPL_ERROR_NULL_INPUT,
        kmo_dfs_save_main_header(fs, "aga", NULL, NULL, NULL, NULL, ""));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    cpl_test_eq(CPL_ERROR_NONE,
        kmo_dfs_save_main_header(fs, "aga", "", NULL, NULL, parl, ""));

    pl = cpl_propertylist_new();
    cpl_test_eq(CPL_ERROR_NONE,
        kmo_dfs_save_main_header(fs, "agaa", "", NULL, pl, parl, ""));

    cpl_propertylist_delete(pl);
    cpl_parameterlist_delete(parl);
    cpl_frameset_delete(fs);
    cpl_free(my_path);
}

/**
 * @brief   test kmo_dfs_save_sub_header()
 */
void test_kmo_dfs_save_sub_header()
{
    cpl_propertylist    *pl         = NULL;

    kmo_test_verbose_off();
    cpl_test_eq(CPL_ERROR_NULL_INPUT,
        kmo_dfs_save_sub_header(NULL, NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(CPL_ERROR_NULL_INPUT,
        kmo_dfs_save_sub_header(NULL, NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(CPL_ERROR_NULL_INPUT,
        kmo_dfs_save_sub_header(NULL, "aga", NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    char *my_path = cpl_sprintf("%s/ref_data/KMOS_dummy.fits", getenv("srcdir"));
    pl = cpl_propertylist_load(my_path, 1);
    cpl_test_eq(CPL_ERROR_NONE,
        kmo_dfs_save_sub_header("agaa", "", pl));

    cpl_propertylist_delete(pl);
    cpl_free(my_path);
}

/**
 * @brief   test kmo_dfs_save_vector()
 */
void test_kmo_dfs_save_vector()
{
    cpl_propertylist  *pl          = cpl_propertylist_new(),
                      *main_header = NULL,
                      *sub_header  = NULL;
    cpl_vector        *v           = cpl_vector_new(3);
    kmclipm_vector    *vec         = NULL;

    kmo_test_fill_vector(v, 0.0, 1.0);
    vec = kmclipm_vector_create(v);

    kmo_test_verbose_off();

    cpl_test_eq(CPL_ERROR_NULL_INPUT,
                kmo_dfs_save_vector(NULL, NULL, NULL, NULL, 0./0.));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_test_eq(CPL_ERROR_NULL_INPUT,
                kmo_dfs_save_vector(NULL, "aga", NULL, NULL, 0./0.));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_test_verbose_on();

    /* save real vector here (first save main header)*/
    cpl_parameterlist   *parl       = cpl_parameterlist_new();
    cpl_frameset        *fs         = cpl_frameset_new();
    char *my_path = cpl_sprintf("%s/ref_data/KMOS_dummy.fits", getenv("srcdir"));
    cpl_frame           *fr         = kmo_test_frame_new( my_path, "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_main_header(fs, "aga_vec", "", NULL, NULL, parl, ""));

    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_vector(NULL, "aga_vec", "", NULL, 0./0.));

    main_header = cpl_propertylist_new();
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_vector(NULL, "aga_vec", "", main_header, 0./0.));

    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_main_header(fs, "aga_vec", "", NULL, NULL, parl, ""));

    sub_header = cpl_propertylist_new();
    kmo_update_sub_keywords(sub_header, FALSE, FALSE, ifu_frame, 1);
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_vector(vec, "aga_vec", "", sub_header, 0./0.));

    cpl_propertylist_delete(main_header);
    cpl_propertylist_delete(sub_header);
    cpl_propertylist_delete(pl);
    kmclipm_vector_delete(vec);
    cpl_frameset_delete(fs);
    cpl_parameterlist_delete(parl);
    cpl_free(my_path);
}

/**
 * @brief   test kmo_dfs_save_image()
 */
void test_kmo_dfs_save_image()
{
    cpl_propertylist *pl          = cpl_propertylist_new(),
                     *main_header = NULL,
                     *sub_header  = NULL;
    cpl_image        *img         = cpl_image_new(2, 2, CPL_TYPE_FLOAT);

    kmo_test_fill_image(img, 0.0, 1.0);

    kmo_test_verbose_off();

    cpl_test_eq(CPL_ERROR_NULL_INPUT,
                kmo_dfs_save_image(NULL, NULL, NULL, NULL, 0./0.));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_test_eq(CPL_ERROR_NULL_INPUT,
                kmo_dfs_save_image(NULL, "aga", NULL, NULL, 0./0.));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_test_verbose_on();

    /* save real image here (first save main header) */
    cpl_parameterlist   *parl       = cpl_parameterlist_new();
    cpl_frameset        *fs         = cpl_frameset_new();
    char *my_path = cpl_sprintf("%s/ref_data/KMOS_dummy.fits", getenv("srcdir"));
    cpl_frame           *fr         = kmo_test_frame_new(my_path, "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_main_header(fs, "aga_img", "", NULL, NULL, parl, ""));

    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_image(NULL, "aga_img", "", NULL, 0./0.));

    main_header = cpl_propertylist_new();
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_image(NULL, "aga_img", "", main_header, 0./0.));

    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_main_header(fs, "aga_img", "", NULL, NULL, parl, ""));
    sub_header = cpl_propertylist_new();
    kmo_update_sub_keywords(sub_header, FALSE, FALSE, detector_frame, 1);
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_image(img, "aga_img", "", sub_header, 0./0.));
    kmo_update_sub_keywords(sub_header, FALSE, FALSE, detector_frame, 2);
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_image(img, "aga_img", "", sub_header, 0./0.));
    kmo_update_sub_keywords(sub_header, FALSE, FALSE, detector_frame, 3);
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_image(img, "aga_img", "", sub_header, 0./0.));

    cpl_propertylist_delete(main_header);
    cpl_propertylist_delete(sub_header);
    cpl_propertylist_delete(pl);
    cpl_image_delete(img);
    cpl_frameset_delete(fs);
    cpl_parameterlist_delete(parl);
    cpl_free(my_path);
}

/**
 * @brief   test kmo_dfs_save_cube()
 */
void test_kmo_dfs_save_cube()
{
    cpl_propertylist *pl          = cpl_propertylist_new(),
                     *main_header = NULL,
                     *sub_header  = NULL;
    cpl_imagelist    *cube        = cpl_imagelist_new();

    kmo_test_alloc_cube(cube, 5, 5, 3);
    kmo_test_fill_cube(cube, 0.0, 1.0);

    kmo_test_verbose_off();

    cpl_test_eq(CPL_ERROR_NULL_INPUT,
                kmo_dfs_save_cube(NULL, NULL, NULL, NULL, 0./0.));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_test_eq(CPL_ERROR_NULL_INPUT,
                kmo_dfs_save_cube(NULL, "aga", NULL, NULL, 0./0.));
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_test_verbose_on();

    /* save real cube here */
    cpl_parameterlist   *parl       = cpl_parameterlist_new();
    cpl_frameset        *fs         = cpl_frameset_new();
    char *my_path = cpl_sprintf("%s/ref_data/KMOS_dummy.fits", getenv("srcdir"));
    cpl_frame           *fr         = kmo_test_frame_new( my_path, "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_main_header(fs, "aga_cube", "", NULL, NULL, parl, ""));

    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_cube(NULL, "aga_cube", "", NULL, 0./0.));

    main_header = cpl_propertylist_new();
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_cube(NULL, "aga_cube", "", main_header, 0./0.));

    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_main_header(fs, "aga_cube", "", NULL, NULL, parl, ""));
    sub_header = cpl_propertylist_new();
    kmo_update_sub_keywords(sub_header, FALSE, FALSE, ifu_frame, 1);
    cpl_test_eq(CPL_ERROR_NONE,
                kmo_dfs_save_cube(cube, "aga_cube", "", sub_header, 0./0.));

    cpl_propertylist_delete(main_header);
    cpl_propertylist_delete(sub_header);
    cpl_propertylist_delete(pl);
    cpl_imagelist_delete(cube);
    cpl_frameset_delete(fs);
    cpl_parameterlist_delete(parl);
    cpl_free(my_path);
}

/**
 * @brief   test kmo_dfs_save_table()
 */
void test_kmo_dfs_save_table()
{
    cpl_frameset *fs = cpl_frameset_new();
    cpl_frame *fr = kmo_test_frame_new("aga_vec.fits", "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);
    cpl_table *t = cpl_table_new(3);
    cpl_propertylist *pl = cpl_propertylist_new();
    cpl_parameterlist *parl = cpl_parameterlist_new();

    kmo_dfs_save_main_header(fs, "aga_table", "", NULL, pl, parl, "");
    cpl_test_error(CPL_ERROR_NONE);
    kmo_dfs_save_table(t, "aga_table", "", pl);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_frameset_delete(fs);
    cpl_table_delete(t);
    cpl_propertylist_delete(pl);
    cpl_parameterlist_delete(parl);
}

/**
 * @brief   test kmo_dfs_get_frame
 */
void test_kmo_dfs_get_frame()
{
    int                 flag        = 0;
    cpl_frameset        *fs         = NULL;
    cpl_frame           *fr         = NULL;

    kmo_test_verbose_off();
    cpl_test_null(kmo_dfs_get_frame(NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    fs = cpl_frameset_new();
    cpl_test_null(kmo_dfs_get_frame(fs, NULL));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    char *my_path = cpl_sprintf("%s/tests/ref_data/KMOS_dummy.fits", getenv("srcdir"));
    fr = kmo_test_frame_new(my_path, "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);
    cpl_frame *ff;
    cpl_test_nonnull(ff = kmo_dfs_get_frame(fs, ""));

    if (ff == fr) {
        flag = TRUE;
    } else {
        flag = FALSE;
    }
    cpl_test_eq(TRUE, flag);

    cpl_frameset_delete(fs);
    cpl_free(my_path);
}

/**
 * @brief   test kmo_dfs_get_parameter_bool
 */
void test_kmo_dfs_get_parameter_bool()
{
    cpl_parameterlist *parl = cpl_parameterlist_new();
    cpl_parameter *par = NULL;

    kmo_test_verbose_off();
    cpl_test_eq(INT_MIN, kmo_dfs_get_parameter_bool(NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(INT_MIN, kmo_dfs_get_parameter_bool(parl, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    cpl_test_eq(INT_MIN, kmo_dfs_get_parameter_bool(parl, "name.bool"));

    par = cpl_parameter_new_value("name.bool", CPL_TYPE_BOOL,
                                  "description.bool", "context.bool", TRUE);
    cpl_parameterlist_append(parl, par);

    cpl_test_eq(TRUE, kmo_dfs_get_parameter_bool(parl, "name.bool"));
    cpl_test_eq(INT_MIN, kmo_dfs_get_parameter_bool(parl, "name.int"));
    cpl_test_error(CPL_ERROR_NONE);

    cpl_parameterlist_delete(parl);
}

/**
 * @brief   test kmo_dfs_get_parameter_int
 */
void test_kmo_dfs_get_parameter_int()
{
    cpl_parameterlist *parl = cpl_parameterlist_new();
    cpl_parameter     *par  = NULL;

    kmo_test_verbose_off();
    cpl_test_eq(INT_MIN, kmo_dfs_get_parameter_int(NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(INT_MIN, kmo_dfs_get_parameter_int(parl, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    cpl_test_eq(INT_MIN, kmo_dfs_get_parameter_int(parl, "name.int"));

    par = cpl_parameter_new_value("name.int", CPL_TYPE_INT,
                                  "description.int", "context.int", 99);
    cpl_parameterlist_append(parl, par);

    cpl_test_eq(99, kmo_dfs_get_parameter_int(parl, "name.int"));
    cpl_test_eq(INT_MIN, kmo_dfs_get_parameter_int(parl, "name.bool"));

    cpl_parameterlist_delete(parl);
}

/**
 * @brief   test kmo_dfs_get_parameter_double
 */
void test_kmo_dfs_get_parameter_double()
{
    cpl_parameterlist *parl = cpl_parameterlist_new();
    cpl_parameter     *par  = NULL;
    float             tol   = 0.01;

    kmo_test_verbose_off();
    cpl_test_abs(-DBL_MAX, kmo_dfs_get_parameter_double(NULL, NULL), tol);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_abs(-DBL_MAX, kmo_dfs_get_parameter_double(parl, NULL), tol);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    cpl_test_abs(-DBL_MAX, kmo_dfs_get_parameter_double(parl, "name.double"), tol);

    par = cpl_parameter_new_value("name.double", CPL_TYPE_DOUBLE,
                                 "description.double", "context.double", 3.123);
    cpl_parameterlist_append(parl, par);

    cpl_test_abs(3.123, kmo_dfs_get_parameter_double(parl, "name.double"), tol);
    cpl_test_abs(-DBL_MAX, kmo_dfs_get_parameter_double(parl, "name.int"), tol);

    cpl_parameterlist_delete(parl);
}

/**
 * @brief   test kmo_dfs_get_parameter_string
 */
void test_kmo_dfs_get_parameter_string()
{
    cpl_parameterlist *parl = cpl_parameterlist_new();
    cpl_parameter *par = NULL;

    kmo_test_verbose_off();
    cpl_test_null(kmo_dfs_get_parameter_string(NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_null(kmo_dfs_get_parameter_string(parl, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    cpl_test_null(kmo_dfs_get_parameter_string(parl, "name.string"));

    par = cpl_parameter_new_value("name.string", CPL_TYPE_STRING,
                                "description.string", "context.string", "gaga");
    cpl_parameterlist_append(parl, par);

    cpl_test_eq_string("gaga", kmo_dfs_get_parameter_string(parl, "name.string"));
    cpl_test_null(kmo_dfs_get_parameter_string(parl, "name.int"));

    cpl_parameterlist_delete(parl);
}

/**
 * @brief   test kmo_dfs_print_parameter_help
 */
void test_kmo_dfs_print_parameter_help()
{
    kmo_test_verbose_off();
    kmo_dfs_print_parameter_help(NULL, NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_parameterlist *p = cpl_parameterlist_new();
    kmo_dfs_print_parameter_help(p, NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    kmo_dfs_print_parameter_help(p, "aga");
    cpl_test_error(CPL_ERROR_NONE);

    cpl_parameter *par = cpl_parameter_new_value("name.bool", CPL_TYPE_BOOL,
                                  "description.bool", "context.bool", TRUE);
    cpl_parameterlist_append(p, par);
    kmo_dfs_print_parameter_help(p, "aga");
    cpl_test_error(CPL_ERROR_NONE);

    cpl_parameterlist_delete(p);
}

/**
 * @brief   test kmo_dfs_get_property_bool
 */
void test_kmo_dfs_get_property_bool()
{
    cpl_propertylist *pl = cpl_propertylist_new();
    cpl_propertylist_append_bool(pl, "bool", FALSE);

    kmo_test_verbose_off();
    cpl_test_eq(INT_MIN, kmo_dfs_get_property_bool(NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(INT_MIN, kmo_dfs_get_property_bool(pl, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(INT_MIN, kmo_dfs_get_property_bool(pl, "int"));
    cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
    kmo_test_verbose_on();

    cpl_test_eq(FALSE, kmo_dfs_get_property_bool(pl, "bool"));

    cpl_propertylist_delete(pl);
}

/**
 * @brief   test kmo_dfs_get_property_int
 */
void test_kmo_dfs_get_property_int()
{
    cpl_propertylist *pl = cpl_propertylist_new();
    cpl_propertylist_append_int(pl, "int", 33);

    kmo_test_verbose_off();
    cpl_test_eq(INT_MIN, kmo_dfs_get_property_int(NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(INT_MIN, kmo_dfs_get_property_int(pl, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(INT_MIN, kmo_dfs_get_property_int(pl, "bool"));
    cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
    kmo_test_verbose_on();

    cpl_test_eq(33, kmo_dfs_get_property_int(pl, "int"));


    cpl_propertylist_delete(pl);
}

/**
 * @brief   test kmo_dfs_get_property_double
 */
void test_kmo_dfs_get_property_double()
{
    cpl_propertylist *pl = cpl_propertylist_new();
    cpl_propertylist_append_double(pl,  "dbl", 2.987);
    float            tol = 0.01;

    kmo_test_verbose_off();
    cpl_test_abs(-DBL_MAX, kmo_dfs_get_property_double(NULL, NULL), tol);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_abs(-DBL_MAX, kmo_dfs_get_property_double(pl, NULL), tol);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_abs(-DBL_MAX, kmo_dfs_get_property_double(pl, "int"), tol);
    cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
    kmo_test_verbose_on();

    cpl_test_abs(2.987, kmo_dfs_get_property_double(pl, "dbl"), tol);

    cpl_propertylist_delete(pl);
}

/**
 * @brief   test kmo_dfs_get_property_string
 */
void test_kmo_dfs_get_property_string()
{
    cpl_propertylist *pl = cpl_propertylist_new();
    cpl_propertylist_append_string(pl, "str", "aga");


    kmo_test_verbose_off();
    cpl_test_null(kmo_dfs_get_property_string(NULL, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_null(kmo_dfs_get_property_string(pl, NULL));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_null(kmo_dfs_get_property_string(pl, "int"));
    cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
    kmo_test_verbose_on();

    cpl_test_eq_string("aga", kmo_dfs_get_property_string(pl, "str"));

    cpl_propertylist_delete(pl);
}

/**
 * @brief   test kmo_identify_index
 */
void test_kmo_identify_index()
{
    cpl_frameset        *fs         = cpl_frameset_new();
    cpl_frame           *fr         = NULL;
    char *my_path = cpl_sprintf("%s/ref_data/KMOS_dummy.fits", getenv("srcdir"));
    fr = kmo_test_frame_new(my_path, "", CPL_FRAME_GROUP_RAW);
    cpl_frameset_insert(fs, fr);

    kmo_test_verbose_off();
    cpl_test_eq(1, kmo_identify_index(my_path, 1, 0));
    cpl_test_eq(2, kmo_identify_index(my_path, 2, 0));
    cpl_test_eq(3, kmo_identify_index(my_path, 3, 0));
    cpl_test_eq(-1, kmo_identify_index(my_path, 4, 0));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_test_eq(-1, kmo_identify_index(my_path, 1, 1));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_test_eq(-1, kmo_identify_index(NULL, 1, 0));
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    cpl_test_eq(-1, kmo_identify_index("aga", 1, 0));
    cpl_test_error(CPL_ERROR_FILE_IO);
    kmo_test_verbose_on();

    cpl_frameset_delete(fs);
    cpl_free(my_path);
}

/**
 * @brief   test kmo_check_lamp
 */
void test_kmo_check_lamp()
{
    kmo_test_verbose_off();
    kmo_check_lamp(NULL, NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_propertylist *p = cpl_propertylist_new();
    kmo_check_lamp(p, NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_propertylist_update_int(p, "aga", 6);
    cpl_test_eq(0, kmo_check_lamp(p, "aga"));
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    cpl_propertylist_delete(p);
    kmo_test_verbose_on();

    p = cpl_propertylist_new();
    cpl_test_eq(0, kmo_check_lamp(p, "aga"));
    cpl_test_error(CPL_ERROR_NONE);

    cpl_propertylist_update_bool(p, "aga", 1);
    cpl_test_eq(1, kmo_check_lamp(p, "aga"));
    cpl_test_error(CPL_ERROR_NONE);

    cpl_propertylist_delete(p);
}

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

    test_strlower();
    test_kmo_extname_extractor();
    test_kmo_extname_creator();
    test_kmo_update_sub_keywords();
    test_kmo_get_index_from_ocs_name();
    test_kmo_dfs_load_primary_header();
    test_kmo_dfs_load_sub_header();
    test_kmo_dfs_save_vector();
    test_kmo_dfs_load_vector();
    test_kmo_dfs_save_image();
    test_kmo_dfs_load_image();
    test_kmo_dfs_load_image_window();
    test_kmo_dfs_load_image_frame();
    test_kmo_dfs_load_image_frame_window();
    test_kmo_dfs_save_cube();
    test_kmo_dfs_load_cube();
    test_kmo_dfs_load_table();
    test_kmo_dfs_create_filename();
    test_kmo_dfs_save_main_header();
    test_kmo_dfs_save_sub_header();
    test_kmo_dfs_save_table();
    test_kmo_dfs_get_frame();
    test_kmo_dfs_get_parameter_bool();
    test_kmo_dfs_get_parameter_int();
    test_kmo_dfs_get_parameter_double();
    test_kmo_dfs_get_parameter_string();
    test_kmo_dfs_print_parameter_help();
    test_kmo_dfs_get_property_bool();
    test_kmo_dfs_get_property_int();
    test_kmo_dfs_get_property_double();
    test_kmo_dfs_get_property_string();
    test_kmo_identify_index();
    test_kmo_check_lamp();

    return cpl_test_end(0);
}

/** @} */
