#ifndef KONOHA_DEBUG_H_
#define KONOHA_DEBUG_H_

/* ======================================================================== */

//#define KONOHA_DEBUGMODE 1
//#define KONOHA_DEMOMODE  1
#define KONOHA_SAFEMODE  1

/* ======================================================================== */
/* KONOHA_TERM */

//#ifdef KONOHA_TERM_COLOR
//#define TERM_INIT          "\x1b[0m"
//#define TERM_COLOR_DEBUG   "\x1b[0;37m"
//#define TERM_COLOR_SAFE    "\x1b[0;33m"
//#define TERM_COLOR_DEMO    "\x1b[0;32m" 
//#else
#define TERM_INIT          ""
#define TERM_COLOR_NOTICE  ""
#define TERM_COLOR_DEBUG   ""
#define TERM_COLOR_SAFE    ""
#define TERM_COLOR_DEMO    ""
//#endif/*KONOHA_TERM_COLOR*/

/* ======================================================================== */
/* KONOHA_DEBUGMODE */

#define KNH_NOTICE(fmt, ...) \
	if(knh_verbose()) { \
		fprintf(stderr, "konoha[%s]: ", __func__); \
		fprintf(stderr, fmt, ## __VA_ARGS__); \
		fprintf(stderr, "\n"); \
	} \
	
/* ======================================================================== */
/* KONOHA_DEBUGMODE */

#ifdef KONOHA_DEBUGMODE

#define DEBUG(fmt, ...) \
	fflush(stdout); \
	fprintf(stderr, TERM_COLOR_DEBUG "\nDEBUG[%s:%d/%s]: ", KNH_SAFEFILE(__FILE__), __LINE__, __func__); \
	fprintf(stderr, fmt, ## __VA_ARGS__); \
	fprintf(stderr, "\n" TERM_INIT); \

#define DEBUG_ASSERT(o)    assert(o)

#define TODO() \
	fprintf(stdout, \
		TERM_COLOR_DEBUG "TODO[%s:%d/%s]:\n" TERM_INIT, \
		__FILE__, __LINE__, __func__); \

#define DEBUG_RESIZE(o, p, os, ns) \
	DEBUG("RESIZE %s(%p) %d => %d", STRUCTN(knh_Object_topsid(o)), o, (int)os, (int)ns); \
	DEBUG("RESIZE old region %p-%p", p , (p + os)); \

#define KNH_ASSERT(o)       assert(o)
#define KNH_FAST_ASSERT(o)  assert(o)


#else /*KONOHA_DEBUGMODE*/

#define DEBUG(fmt, ...)
#define DUMP(ctx, o)
#define DEBUG_ASSERT(o)
#define TODO()

#define DEBUG_RESIZE(o, p, os, ns) 

#define KNH_ASSERT(o)
#define KNH_FAST_ASSERT(o)

#endif/*KONOHA_DEBUGMODE*/
	

/* ======================================================================== */
/* KONOHA_SAFEMODE */

#ifdef KONOHA_SAFEMODE

#define KNH_TODO(msg) \
	fprintf(stdout, \
		TERM_COLOR_SAFE "TODO[%s:%d/%s]:\n\t%s\n" TERM_INIT, \
		__FILE__, __LINE__, __func__, msg); \

#define KNH_TODO64(msg) \
	fprintf(stdout, \
		TERM_COLOR_SAFE "TODO64[%s:%d/%s]:\n\t%s\n" TERM_INIT, \
		__FILE__, __LINE__, __func__, msg); \

#define KNH_MEMO(fmt, ...) \
	fprintf(stdout, TERM_COLOR_SAFE "MEMO[%s:%d/%s]:\n", __FILE__, __LINE__, __func__); \
	fprintf(stderr, fmt, ## __VA_ARGS__); \
	fprintf(stderr, TERM_INIT "\n"); \

#define SAFE_SETr(ctx, sf, o)       KNH_SETr(ctx, sf, o)

#else /*KONOHA_SAFEMODE*/

#define KNH_TODO(msg)
#define KNH_TODO64(msg)
#define KNH_MEMO(fmt, ...)

#define SAFE_SETr(ctx, sf, o)       KNH_SETr(ctx, sf, o)

#endif/*KONOHA_SAFEMODE*/

/* ======================================================================== */
/* KONOHA_DEMOMODE */

#ifdef KONOHA_DEMOMODE

#define DEMO_DUMP(ctx, o, opt, msg) \
	fprintf(stdout, TERM_COLOR_DEMO "DEMO[%s]: %s\n", __func__, msg); \
	knh_format(ctx, StdOut, METHODN__dump, o, opt); \
	fprintf(stdout, "\n" TERM_INIT); \

#else /*KONOHA_SAFEMODE*/

#define DEMO_DUMP(ctx,o, opt, msg)

#endif/*KONOHA_SAFEMODE*/

#endif /*KONOHA_DEBUG_H_*/
