#ifndef TEST_H
#define TEST_H

#include <iostream>
#include <sstream>
#include <stdint.h>
#include "Common/include/Message.h"
#include "Common/include/ErrorMorpheo.h"
#include "Common/include/ToString.h"

//-----[ Routine de test ]---------------------------------------

static uint32_t num_test;

inline void test_ko_error (void)
{
  string msg = "Test ko : error in test \""+morpheo::toString(num_test)+"\"";
  throw (morpheo::ErrorMorpheo (msg));
}
  
template <class T>
inline void test_ko (char * file, uint32_t line, T exp1, T exp2)
{
  cerr << "[" << num_test << "] : Test KO"
       << "\tline " << line                           << endl
       << " * Localisation"                           << endl
       << "   - File : " << file                      << endl
       << "   - Line : " << line                      << endl
       << " * Expression is different"                << endl
       << "   - exp1 : "+morpheo::toString(exp1)               << endl
       << "   - exp2 : "+morpheo::toString(exp2)               << endl;

  test_ko_error ();
};

inline void test_ko (char * file, uint32_t line)
{
  cerr << "[" << num_test << "] : Test KO"
       << "\tline " << line                           << endl
       << " * Localisation"                           << endl
       << "   - File : " << file                      << endl
       << "   - Line : " << line                      << endl;
  
  test_ko_error ();
};

inline void test_ok ()
{
  msg (_("[%d] : Test OK\n"), num_test);

  num_test ++;
};

inline void test_ok (char * file, uint32_t line)
{
  msg (_("[%d] : Test OK\n"), num_test);
  msg (_("\tline %d\n"), line);

  num_test ++;
};

template <class T>
inline void test_ok (char * file, uint32_t line, T exp)
{
  msg (_("[%d] : Test OK\n"), num_test);
  msg (_("\tline %d\n"), line);
  msg (_("\tvalue %s\n"), (morpheo::toString(exp)).c_str());

  num_test ++;
}

template <class T>
inline void test(char * file, uint32_t line, T exp1, T exp2)
{
  if (exp1 != exp2)
    test_ko <T> (file,line,exp1,exp2);
  else
    test_ok <T> (file,line,exp1);
};

#define TEST(type,exp1,exp2)            do {test<type> (__FILE__,__LINE__,exp1,exp2);} while(0)
#define TEST_STR(type,exp1,exp2,str...) do {fprintf(stdout,str); fprintf(stdout,"\n"); test<type> (__FILE__,__LINE__,exp1,exp2);} while(0)
#define TEST_OK(str...)                 do {fprintf(stdout,str); fprintf(stdout,"\n"); test_ok(__FILE__,__LINE__);} while(0)
#define TEST_KO(str...)                 do {fprintf(stdout,str); fprintf(stdout,"\n"); test_ko(__FILE__,__LINE__);} while(0)


#endif
