//----------------------------------------------------------------------------
///
/// \file   tests_retain.cpp
///
/// \brief  counter
///
/// \date   20210922
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


//---Documentation------------------------------------------------------------


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


//---General--------------------------

#if defined ( CATCH_V3 )
   #include <catch2/catch_test_macros.hpp>
#elif defined ( CATCH_V2 )
   #include <catch2/catch.hpp>
#elif defined ( CATCH_V1 )
   #include <catch/catch.hpp>
#else
   #error "Either 'catch' or 'catch2' has to be installed"
#endif

#include <string.h>

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

#include <lepto/log.h>
#include <lepto/ring.h>
#include <biwak/log_private.h>
#include <biwak/led.hpp>
#include <biwak/heartbeat.hpp>
#include <biwak/output_blink_modes.h>

#define TEST_ALL
#define STOP_ON_FAIL


//---Implementation------------------------------------------------------------


TEST_CASE( "Logging", "[default]" )
{
   SECTION( "Simple" )
   {
      int pushClearance = LEPTO_RING_PUSH_CLEARANCE;
      logEventLoop();

      REQUIRE ( logPending() == nullptr );

      // Check: last character is '8'
      bWarning( "Log output: 0x%X", 0x12345678 );

      // The result is (Category not part of the string: W: E:...):
      // "Log output: 0x12345678"
      //                    |- limited with max length 20

      REQUIRE ( logPending() != nullptr );
      const char* _logPending=logPending();

      if( _logPending )
      {
         printf( "Pending: 0x%p / %s\n", _logPending, _logPending );

         if( MAX_LOG_STRING == 20 )
         {
            REQUIRE ( logPending()[ strlen(logPending()) - 1 ] == '5' );
         }
         else
         {
            REQUIRE ( logPending()[ strlen(logPending()) - 1 ] == '8' );
         }
      }

      logEventLoop();

      // Check: size is limited
      bWarning( "Log  12345678901234567890" "12345678901234567890"
                     "12345678901234567890" "12345678901234567890"
                     "12345678901234567890" "12345678901234567890"
                     "12345678901234567890" "12345678901234567890"
                );
      REQUIRE ( strlen(logPending()) == MAX_LOG_STRING - 1 );

      // Check: Fill all available entries
      for(int i1=0; i1<MAX_LOG_ENTRIES; i1++)
      {
         bInfo( "Log output %d", i1 );
      }
      REQUIRE ( logPendingCount() == MAX_LOG_ENTRIES - pushClearance );

      // Check: Event loop clears all log entries
      logEventLoop();
      REQUIRE ( logPendingCount() == 0 );

      //REQUIRE ( heartBeatImplementation() == 42 );
   }

   // This is part of lof_heartbeat.cpp
   #if 0
   SECTION( "Heartbeat" )
   {
      CLed led( eGpioPeripheralA, eGpioPin1 );
      CHeartBeat heartbeat( led );

      REQUIRE ( led.getBlinkMode() == BlinkModes::_double );

      #if ! IS_ENABLED( BIWAK_LOG_HEARTBEAT )
         #error BIWAK_LOG_HEARTBEAT not enabled. Need this for testing
      #endif // ? BIWAK_LOG_HEARTBEAT

      // Check: Blink on warning/trouble
      bWarning("Could not receive anything.");
      heartbeat.eventLoop();

      INFO("Want HB Error:");
      REQUIRE ( led.getBlinkMode() == BlinkModes::error );

      // Check: Recover from warning, but not too soon. Duration for x86: 3 sec.
      usleep( 2 * USECS_PER_SEC );
      heartbeat.eventLoop();

      INFO("Want HB Error 2:");
      REQUIRE ( led.getBlinkMode() == BlinkModes::error );

      usleep( 4 * USECS_PER_SEC );
      heartbeat.eventLoop();

      INFO("Want HB calmed:");
      REQUIRE ( led.getBlinkMode() == BlinkModes::_double );

      bCritical("EEPROM is damaged");
      heartbeat.eventLoop();
      REQUIRE ( led.getBlinkMode() == BlinkModes::blink );
   }
   #endif // ? 0
}


//---fin-----------------------------------------------------------------------
