//----------------------------------------------------------------------------
///
/// \file   test_time.cpp
///
/// \brief  Tests for time function overloading libc implementation
///
/// \date   20241114
/// \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 <biwak/rtc.hpp>

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

#define TEST_ALL
#define STOP_ON_FAIL

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

#define matchDate(year, month, mday, hour, minute, second) \
         REQUIRE ( t->tm_year == year - 1900 ); \
         REQUIRE ( t->tm_mon == month - 1 ); \
         REQUIRE ( t->tm_mday == mday ); \
         REQUIRE ( t->tm_hour == hour ); \
         REQUIRE ( t->tm_min == minute ); \
         REQUIRE ( t->tm_sec == second );

#if 0
   #define     xGmtime     gmtime
   #define     xLocaltime  localtime
#else
   #define     xGmtime     bGmtime
   #define     xLocaltime  bLocaltime
#endif

TEST_CASE( "Time", "[default]" )
{

   SECTION( "UTC" )
   {
      time_t testTime=time( nullptr );
      struct tm* t= gmtime(&testTime);
      
      // 0: 1. Jan. 1970   00:00:00
      INFO( "Year 1970" );
      testTime=0;
      t= xGmtime(&testTime);
      matchDate(1970, 1, 1, 0, 0, 0);
      
      // 1000000000: 9. Sep. 2001   01:46:40
      INFO( "Year 2001" );
      testTime=1000000000;
      t= xGmtime(&testTime);
      matchDate(2001, 9, 9, 1, 46, 40);
      
      // 2147483647 	7FFFFFFF: 19. Jan. 2038   03:14:07
      INFO( "Year 2038" );
      testTime=0x7FFFFFFF;
      t= xGmtime(&testTime);
      matchDate(2038, 1, 19, 3, 14, 07);
      
      // Wed Mar 16 2242 12:56:32 GMT+0000
      INFO( "Year 2242" );
      testTime=0x200000000;
      t= xGmtime(&testTime);
      matchDate(2242, 3, 16, 12, 56, 32);
      
      // Check if assumption is correcto for localtime-tests
      // 31.3.2024 1:59:59 MEZ -> 1711846799
      INFO( "Localtime" );
      testTime=1711846799;
      t= xGmtime(&testTime);
      matchDate(2024, 3, 31, 0, 59, 59);
      
      // Check if assumption is correcto for localtime-tests
      // 31.3.2024 2:00:00 MEZ (does not exist, increase 1:59:59 by one)
      INFO( "Localtime" );
      testTime=1711846799+1;
      t= xGmtime(&testTime);
      matchDate(2024, 3, 31, 1, 0, 0);
   }
   
   SECTION( "localtime" )
   {
      time_t testTime=time( nullptr );
      struct tm* t= gmtime(&testTime);
      
      // Last sunday in march 2024: 31.3.2024
      // 31.3.2024 1:59:59 MEZ -> 1711846799
      INFO( "MEZ" );
      testTime = 1711846799;
      t= xLocaltime(&testTime);
      matchDate(2024, 3, 31, 1, 59, 59);
      
      INFO( "Switch to MESZ" );
      testTime = 1711846799 + 1;
      t= xLocaltime(&testTime);
      matchDate(2024, 3, 31, 3, 0, 0);
      
      // 27.10.2024 2:59:59 MESZ -> 1729990799
      INFO( "MESZ" );
      testTime = 1729990799;
      t= xLocaltime(&testTime);
      matchDate(2024, 10, 27, 2, 59, 59);
      
      INFO( "Switch to MEZ" );
      testTime = 1729990799 + 1;
      t= xLocaltime(&testTime);
      matchDate(2024, 10, 27, 2, 0, 0);
      
      // 31.12.2024 23:30:00 UTC -> 1735687800
      INFO( "Overlap year because of timezone" );
      testTime = 1735687800;
      t= xGmtime(&testTime);
      printf("UTC %d.%d.%d %d:%d:%d\n", t->tm_year+1900, t->tm_mon+1, t->tm_mday,
             t->tm_hour, t->tm_min, t->tm_sec);
      matchDate(2024, 12, 31, 23, 30, 0);
      
      t= xLocaltime(&testTime);
      printf("MEZ %d.%d.%d %d:%d:%d\n", t->tm_year+1900, t->tm_mon+1, t->tm_mday,
             t->tm_hour, t->tm_min, t->tm_sec);
      matchDate(2025, 1, 1, 0, 30, 0);
   }
}


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