#ifndef _fencer_debug_h
#define _fencer_debug_h

#include <stdio.h>
#include <stdlib.h>

#ifndef NDEBUG
#include <assert.h>
#endif

extern int g_debug_error_abort;
extern int g_debug_log_lvl;

#define LOG_INFO(...) do {\
    if(g_debug_log_lvl < 3) break;\
    printf("[%s:%d]  INFO | ", __FILE__, __LINE__);\
    printf(__VA_ARGS__);\
    printf("\n");\
} while(0)

#define LOG_ERROR(...) do {\
    if(g_debug_log_lvl >= 1) {\
        printf("[%s:%d]  ERROR | ", __FILE__, __LINE__);\
        printf(__VA_ARGS__);\
        printf("\n");\
        fflush(stdout);\
    }\
    if(g_debug_error_abort != 0) abort();\
} while(0)

#define LOG_WARNING(...) do {\
    if(g_debug_log_lvl < 2) break;\
    printf("[%s:%d]  WARNING | ", __FILE__, __LINE__);\
    printf(__VA_ARGS__);\
    printf("\n");\
} while(0)


#define RETURN_ERROR(__VALUE, ...) do {\
    LOG_ERROR(__VA_ARGS__);\
    return __VALUE;\
} while(0)

#define RETURN_WARNING(__VALUE, ...) do {\
    LOG_WARNING(__VA_ARGS__);\
    return __VALUE;\
} while(0)

#define ASSERT_RETURN(__ASSERT, __RETURN, ...) do {\
    if(!(__ASSERT)) {\
        LOG_ERROR(__VA_ARGS__);\
        return __RETURN;\
    }\
} while(0)

#define CHECK(__ASSERT, ...) do {\
    if(!(__ASSERT)) {\
        LOG_ERROR(__VA_ARGS__);\
    }\
} while(0)

#define ASSERT_RETURN_WARN(__ASSERT, __RETURN, ...) do {\
    if(!(__ASSERT)) {\
        LOG_WARNING(__VA_ARGS__);\
        return __RETURN;\
    }\
} while(0)

#endif // !_fencer_debug_h
