#ifndef BIWAK_LOG_H
#define BIWAK_LOG_H
//----------------------------------------------------------------------------
///
/// \brief  Logging
///
//
/// \date   20221222
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


//---Includes-----------------------------------------------------------------


//---Own------------------------------

#include <lepto/log.h>         // ELogCategory
#include <lepto/lepto.h>       // defaults CONFIG_LEPTO_LOG_USE_PRETTY_PRINT
#if IS_ENABLED( CONFIG_BIWAK_LOG_USE_TIMESTAMPS )
#include <biwak/timer.hpp>
#endif


//---Defines------------------------------------------------------------------


#if ( ! defined ( MCU_RAM_SIZE ) ) || ( MCU_RAM_SIZE > 0x1000 )
   #define BIWAK_LONG_LOG  1
#else
   #define BIWAK_SHORT_LOG  1
#endif

#if 0
#if defined BIWAK_LONG_LOG
   #define MAX_LOG_STRING 60
   #define MAX_LOG_ENTRIES 24
#else
   // Less than 40 cuts many logs
   #define MAX_LOG_STRING 20
   #define MAX_LOG_ENTRIES 4
#endif
#endif

// At least unit tests need bigger strings
#if IS_ENABLED( CONFIG_LEPTO_LOG_USE_PRETTY_PRINT )
   // Less than 40 cuts many logs
   #define MAX_LOG_STRING 40
   //#define MAX_LOG_ENTRIES 24
   #define MAX_LOG_ENTRIES 48
#else
   #define MAX_LOG_STRING 20
   // Entries: 4 not enough for mainswitch, 7 not for miniminutnik
   #define MAX_LOG_ENTRIES 8
#endif

#if ! defined CONFIG_LEPTO_LOG_USE_PRETTY_PRINT
   #if ! defined CONFIG_LEPTO_LOG_DOWNSIZE
      #error LEPTO_LOG_USE_PRETTY_PRINT is not defined but LEPTO_LOG_DOWNSIZE \
             also not. This will lead to cut messages when using biwak.
   #endif
#endif


//---Declaration--------------------------------------------------------------


#if defined BIWAK_LOG_DEBUG
   #define bDebug( ... ) bDebugReal( __VA_ARGS__ )
#else
   #define bDebug(a,...)
#endif

struct SLogEntry
{
   #if IS_ENABLED( CONFIG_LEPTO_LOG_USE_PRETTY_PRINT )
      const char *file;
      int line;
   #endif
      
   #if IS_ENABLED( CONFIG_BIWAK_LOG_USE_TIMESTAMPS )
      lrtimer_t timeStamp;
   #endif
      
   ELogBlended code;

   #if IS_ENABLED( CONFIG_BIWAK_LOG_EVENTS )
   //unsigned int event;
   #endif

   #if ! IS_ENABLED( CONFIG_LEPTO_LOG_SILENT )
   char logString[MAX_LOG_STRING];
   #endif
};

#if ! IS_ENABLED( CONFIG_LEPTO_LOG_SILENT )
   #define bDebugReal(msg, ...) bLogChooser(ELogCategory::Debug|0, msg, ##__VA_ARGS__ )
   #define bInfo(msg, ...) bLogChooser(ELogCategory::Info|0, msg, ##__VA_ARGS__ )
   #define bWarning(msg, ... ) bLogChooser(ELogCategory::Warning|0, msg, ##__VA_ARGS__ )
   #define bCritical(msg, ... ) bLogChooser(ELogCategory::Critical|0, msg, ##__VA_ARGS__ )
   #define bFatal(msg, ... ) bLogChooser(ELogCategory::Fatal|0, msg, ##__VA_ARGS__ )
#else
   #define bDebugReal(msg, ...)
   #define bInfo(msg, ...)
   #define bWarning(msg, ... )
   #define bCritical(msg, ... )
   #define bFatal(msg, ... )
#endif

#if IS_ENABLED( CONFIG_LEPTO_LOG_USE_PRETTY_PRINT )
   #define bLogChooser( ... ) bLogPP( __FILE_NAME__, __LINE__, __VA_ARGS__)
#else
   #define bLogChooser( ... ) bLog( __VA_ARGS__ )
#endif

extern "C"
{
   void bVLog(ELogBlended code, const char *format, va_list &list );
   void bVLogPP(const char*file, int line, ELogBlended code, const char *format, va_list &list );
   void bLog(ELogBlended code, const char *format, ... );
   void bLogPP(const char*file, int line, ELogBlended code, const char *format, ... );
   /*
   void bInfo(const char *format, ... );
   void bWarning(const char *format, ... );
   void bCritical(const char *format, ... );
   void bFatal(const char *format, ... );
   */
   int bLogInfo();
}
   
#if IS_ENABLED( CONFIG_BIWAK_LOG_CUSTOM_CHANNEL )
   void logCustomChannel( ELogBlended code, const char* message );
#endif


int logPendingCount();
void logEventLoop();
const char *logPending();
void logAutoFlush();
void logEventLoop();


//---fin----------------------------------------------------------------------
#endif // ? ! BIWAK_LOG_H
