/*!
 * \file    config,h
 * \brief   Build configuration file.
 *
 * \author
 *    Christos Choutouridis AEM:8997
 *    <cchoutou@ece.auth.gr>
 */

#ifndef CONFIG_H_
#define CONFIG_H_

#include <iostream>
#include <string>

#include "matrix.hpp"

// HDF5 supported types
enum class HDF5_type {
   SCHAR, CHAR, SHORT, USHORT, INT, UINT, LONG, ULONG, LLONG, ULLONG, FLOAT, DOUBLE
};

/*
 * Defines for different version of the exercise
 */
#define  V0    0
#define  V1    1


// Fail-safe version selection
#if !defined CODE_VERSION
 #define CODE_VERSION   V1
#endif

// matrix alias template dispatcher
using MatrixDst = mtx::Matrix<double>;
using MatrixIdx = mtx::Matrix<uint32_t>;
static constexpr HDF5_type DstHDF5Type = HDF5_type::DOUBLE;
static constexpr HDF5_type IdxHDF5Type = HDF5_type::INT;


//! enumerator for output handling
enum class StdOutputMode{ STD, FILE };

/*!
 * Session option for each invocation of the executable
 */
struct session_t {
   std::string   corpusMtxFile  {};                        //!< corpus matrix file name in HDF5 format
   std::string   corpusDataSet  {};                        //!< corpus dataset name in HDF5 matrix file
   std::string   queryMtxFile   {};                        //!< optional query matrix file name in HDF5 format
   std::string   queryDataSet   {};                        //!< optional query dataset name in HDF5 matrix file
   bool          queryMtx       {false};                   //!< Flag to indicate that there is a separate query matrix
   size_t        k              {1};                       //!< The number of nearest neighbors to find
   std::string   outMtxFile     {"out.hdf5"};              //!< output matrix file name in HDF5 format
   std::string   outMtxIdxDataSet {"/Idx"};                //!< Index output dataset name in HDF5 matrix file
   std::string   outMtxDstDataSet {"/Dst"};                //!< Distance output dataset name in HDF5 matrix file
   std::size_t   max_threads    {0};                       //!< Maximum threads to use
   std::size_t   slices         {0};                       //!< Slices/threads to use
   std::size_t   accuracy       {100};                     //!< The neighbor finding accuracy
   bool          timing         {false};                   //!< Enable timing prints of the program
   bool          verbose        {false};                   //!< Flag to enable verbose output to stdout
};

extern session_t session;

#endif /* CONFIG_H_ */
