#ifndef Morpheo_Test_h
#define Morpheo_Test_h

/*
 * $Id: Test.h 113 2009-04-14 18:39:12Z rosiere $
 *
 * [ Description ]
 * 
 * Macro / function to test
 */

#include <iostream>
#include <sstream>
#include <stdint.h>
#include "Common/include/Message.h"
#include "Common/include/ErrorMorpheo.h"
#include "Common/include/ToString.h"
#include "Common/include/Systemc.h"
namespace morpheo {

#define STR_OK "Test OK"
#define STR_KO "Test KO"

static uint32_t num_test;

inline void test_ko_error (void)
{
  std::string msg = morpheo::toString(_("Test ko : error in test \"%d\""),num_test);
  throw (morpheo::ErrorMorpheo (msg));
}
  
template <class T>
inline void test_ko (char * file, uint32_t line, T exp1, T exp2)
{
  msgError(_("[%d] : %s\n"),num_test,STR_KO);
  msgError(_(" * Localisation\n"));
  msgError(_("   - File  : %s\n"),file);
  msgError(_("   - Line  : %d\n"),line);
  msgError(_(" * Expression is different\n"));
  msgError(_("   - exp1  : %s\n"),morpheo::toString(exp1).c_str());
  msgError(_("   - exp2  : %s\n"),morpheo::toString(exp2).c_str());

  test_ko_error ();
};

inline void test_ko (char * file, uint32_t line)
{
  msgError(_("[%d] : %s\n"),num_test,STR_KO);
  msgError(_(" * Localisation\n"));
  msgError(_("   - File  : %s\n"),file);
  msgError(_("   - Line  : %d\n"),line);
  
  test_ko_error ();
};

inline void test_ok ()
{
  msgInformation (_("[%d] : %s\n"), num_test,STR_OK);

  num_test ++;
};

inline void test_ok (char * file, uint32_t line)
{
  msgInformation (_("[%d] : %s (line %d)\n"), num_test,STR_OK,line);
  msgInformation (_("   - Line  : %d\n"), line);

  num_test ++;
};

template <class T>
inline void test_ok (char * file, uint32_t line, T exp)
{
  msgInformation (_("[%d] : %s\n"), num_test, STR_OK);
  msgInformation (_("   - Line  : %d\n"), line);
  msgInformation (_("   - Value : %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 {morpheo::test<type> (__FILE__,__LINE__,exp1,exp2);} while(0)
#define TEST_STR(type,exp1,exp2,str...) do {fprintf(stdout,str); fprintf(stdout,"\n"); morpheo::test<type> (__FILE__,__LINE__,exp1,exp2);} while(0)
#define TEST_OK(str...)                 do {fprintf(stdout,str); fprintf(stdout,"\n"); morpheo::test_ok(__FILE__,__LINE__);} while(0)
#define TEST_KO(str...)                 do {fprintf(stdout,str); fprintf(stdout,"\n"); morpheo::test_ko(__FILE__,__LINE__);} while(0)

#define LABEL(str...)							\
  {									\
    msgInformation (_("{%.0f} "),simulation_cycle());                \
    msg            (str);                                               \
    msg            (_("\n"));                                           \
  } while(0)

#ifndef CYCLE_MAX
# error "CYCLE_MAX must be defined";
#endif

#define SC_CYCLE(cycle_offset)						\
  do									\
    {									\
      /*cout << "SC_CYCLE (begin)" << endl;*/				\
      									\
      double cycle_current = simulation_cycle();                        \
      if (cycle_offset != 0)						\
	{								\
	  msgInformation(_("##########[ cycle %.0f ] (%d)\n"),cycle_current+cycle_offset,__LINE__); \
	}								\
      									\
      if ((CYCLE_MAX != 0) and (cycle_current > CYCLE_MAX))             \
	{								\
	  TEST_KO("Maximal cycles Reached");				\
	}								\
      									\
      simulation_run(cycle_offset);                                     \
      									\
      /*cout << "SC_CYCLE (end  )" << endl;*/				\
    } while(0)

// old support
#ifndef MTI_SYSTEMC
# define SC_START(x) SC_CYCLE(x)
#endif

};
#endif
