//----------------------------------------------------------------------------
///
/// \file   main.cpp
///
/// \brief  main file for pinmux
///
/// \date   20180129
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


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


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


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

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

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

#include "../src/board.h"
#include "../src/app.h"
#include "../src/pinmux.h"
#include "writerPlatform.h"
#include "formaterCpp.h"

#define TEST_ALL
#define STOP_ON_FAIL

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


TEST_CASE( "Overload", "[default]" ) {
   CPinmux pinmux;
   CApp app;
   CBoard board;

   SECTION( "Overload speed attribute from app" )
   {
      const char *boardString=
      R"JSON(
      {
          "name": "Nucleo_f303_Overload",
          "version": "1",
          "overloadingAttributes": [ "speedo" ],
          "peripheries": [
                  { "type": "GPIO",   "periphery": "PA12", "pin": "D1", "irq": "EXTI9_5_IRQHandler" },
                  { "type": "GPIO",   "periphery": "PA11", "pin": "D0", "irq": "EXTI15_10_IRQHandler" },
                  {
                     "type": "SPI", "periphery": "SPI1.PA11", "irqs": "SPI_IRQHandler",
                     "consumes": [
                         { "periphery": "PA12",   "name": "TX", "mode": "skip" },
                         { "periphery": "PA11",   "name": "RX", "mode": "skip" }
                     ],
                     "attributes": {
                         "configBlock": "SPI1_PA12_PA11",
                         "speedo": "10Khz",
                         "implementation": "10Khz"
                     }
                  }
         ],
         "constructors": [
                 {
                     "type": "SPI",
                     "arguments": [
                             { "type": "fixed", "value": "spiConfig_<attribute:configBlock>" },
                             { "type": "fixed", "value": "spiConfig_<attribute:speedo>" }
                     ]
                 }
         ],
         "final": "yes"
      }
      )JSON";

      app.clear();
      board.clear();
      board.loadByteArray( QByteArray(boardString), "intern_SPI" );
      app.loadByteArray(
               QByteArray(R"JSON(
               {
                   "name": "canio",
                   "periphery": [
                      { "type": "SPI", "name": "1",
                           "attributes": {
                               "speedo": "24Mhz"
                           }
                      }
                   ]
               }
      )JSON" ), "intern" );

      pinmux.setBoardApp(board, app);
      pinmux.resolveApp();
      CConstructorPool pool;
      pool.loadByteArray( QByteArray(boardString), "intern" );
      CWriterPlatform platform(pinmux, pool, "");

      CPeripheryPtr ptr=board.findPeripheryByPeripheryName( QString("SPI1.PA11") );
      qWarning() << "OUTPUT: " << platform.getPeripheralArgumentsString( *ptr );

      REQUIRE( platform.getPeripheralArgumentsString( *ptr )
               == "spiConfig_SPI1_PA12_PA11, spiConfig_24Mhz");
   }

   SECTION( "Must not overload 'configBlock'" )
   {
      const char *boardString=
      R"JSON(
      {
          "name": "Nucleo_f303_overload_config_block",
          "version": "1",
          "peripheries": [
              { "type": "GPIO",   "periphery": "PA4",  "pin": "PA4/#10", "irqs": "EXTI4_15_IRQHandler" },
              { "type": "TIMER",   "periphery": "TIM14", "name": ""
                     ,"irqs": "TIM14_IRQHandler", "mode": "shared",
                     "attributes": {
                        "configBlock": "timerConfig_TIM14"
                     }
              },
              {
                  "type": "PWM",
                  "consumes": [
                      { "periphery": "PA4",  "name": "_TIM14_CH1", "mode": "skip" },
                      { "periphery": "TIM14","useIrq": "yes", "mode": "shared", "__mode": "skip" }
                  ],
                  "_arguments": [ { "value": "eTimerChannel1", "position": 3 } ],
                  "attributes": {
                      "configBlock": "pwmConfig_TIM14_CH1_PA4"
                  }
              }
         ],
         "constructors": [
                 { "type": "PWM", "arguments": [ ] },
                 { "type": "TIMER",
                     "arguments": [
                            { "type": "fixed", "value": "<attribute:configBlock>" }
                     ]
                 }
         ],
         "final": "yes"
      }
      )JSON";

      app.clear();
      board.clear();
      board.loadByteArray( QByteArray(boardString), "intern_WKUP" );
      app.loadByteArray(
               QByteArray(R"JSON(
               {
                   "name": "canio",
                   "periphery": [
                      { "type": "PWM", "name": "1" }
                   ]
               }
               )JSON" ), "intern" );

      pinmux.setBoardApp(board, app);
      pinmux.resolveApp();

      CPeripheryPtr p=board.findPeripheryByPeripheryName( QString("TIM14") );
      REQUIRE( p != nullptr );
      qWarning() << "Output: " << p->getAttribute( "configBlock" );
      REQUIRE( ( p->getAttribute( "configBlock" ) ) == "timerConfig_TIM14" );

      CConstructorPool constructors;
      constructors.loadByteArray( QByteArray(boardString), "intern" );
      CWriterPlatform platform(pinmux, constructors, "");

      qWarning() << "Output: " << platform.getPeripheralArguments(*p)[0];

      REQUIRE( platform.getPeripheralArguments(*p)[0] == "timerConfig_TIM14" );
   }
}


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