//----------------------------------------------------------------------------
///
/// \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

//--- 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( "Constructor", "[default]" ) {
   CPinmux pinmux;
   CApp app;
   CBoard board;

   SECTION( "find periphery by alternate function" )
   {
      const char *boardString=
      R"JSON(
      {
          "name": "board_placeholder",
          "version": "1",
          "peripheries": [
             { "type": "GPIO", "periphery": "PA1" },
             { "type": "GPIO", "periphery": "PA2" },
             { "type": "GPIO", "periphery": "PA3" },
             { "type": "GPIO", "periphery": "PA4" },
             { "type": "GPIO", "periphery": "PB1" },
             { "type": "GPIO", "periphery": "PA5" },
             {
                 "type": "OUTPUT", "name": "OUTPUT", "relation": "fabricate",
                 "consumes": [   { "type": "GPIO", "name": "OUTPUT" }   ]
             },
             {
                 "type": "SPI", "periphery": "SPI1",
                 "consumes": [
                         { "periphery": "PA1",   "name": "SCK", "mode": "skip" },
                         { "periphery": "PA2",   "name": "MISO", "mode": "skip" },
                         { "periphery": "PA3",   "name": "MOSI", "mode": "skip" }
                 ],
                 "attributes": { "configBlock": "aaa"}
             },
             {
                 "type": "DISPLAY", "name": "DISPLAY", "periphery": "DISPLAY", "relation": "normal",
                 "consumes": [
                     { "type": "SPI",   "name": "", "pin": "[SCL@#6 MOSI@#5 MISO@#2]", "relation": "shared" },
                     { "type": "GPIO",  "name": "BP", "_name": "CS", "pin": "#1" }
                 ]
             },
             { "type": "INPUT",  "periphery": "INPUT_PA5", "name": "1", "relation": "-",
               "consumes": [
                     { "periphery": "PA5",   "name": "INPUT" },
                     { "periphery": "EXTI5",   "name": "0", "relation": "shared" }
               ],
               "attributes": {
                     "irqs": "EXTI5_IRQHandler",
                     "configBlock": "extiConfig_EXTI5_input"
               }
             },
             {   "type": "EXTI", "periphery": "EXTI5", "name": "EXTI5", "relation": "shared",
                  "attributes": {
                        "irqs": "EXTI5_IRQHandler",
                        "configBlock": "extiConfig_EXTI5",
                        "implementation": [
                              "static constexpr SExtiConfig extiConfig_EXTI5",
                              "{",
                              "   EXTI5_IRQn,",
                              "   interruptExti5,",
                              "};",
                              ""
                         ]
                   }
             }
          ],
          "constructors": [
              {
                  "type": "GPIO",
                  "constructorArgument": "eGpioPeripheral<PeripheryBlock>, eGpioPin<PeripheryNumber>",
                  "attributeName": "<unlikely>",
                  "arguments": [
                         { "type": "fixed", "value": "eGpioPeripheral<PeripheryBlock>" },
                         { "type": "fixed", "value": "eGpioPin<PeripheryNumber>" }
                  ]
              },
              {   "type": "OUTPUT", "constructorArgument": "",
                    "arguments": [
                           { "type": "consumes", "value": "direct" }
                    ]
              },
              {
                  "type": "SPI", "_constructorArgument": "eUart<PeripheryNumber>",
                        "constructorArgument": " uartConfig_<attribute:configBlock> ",
                        "arguments": [
                           { "type": "fixed", "value": "<attribute:configBlock>" }
                        ]
              },
              {   "type": "DISPLAY", "constructorArgument": "",
                    "arguments": [
                           { "type": "consumes", "value": "indirect" },
                           { "type": "consumes", "value": "direct" }
                    ]
              },
              {   "type": "INPUT", "class": "CInput",
                  "arguments": [
                     { "type": "consumes", "value": "direct" }
                  ]
              },
              {   "type": "EXTI",
                  "arguments": [
                          { "type": "fixed", "value": "<attribute:configBlock>" }
                  ]
              }
         ],
         "final": "yes"
      }
      )JSON";

      app.clear();
      board.clear();
      app.setBoardId("myboard");
      board.loadByteArray( QByteArray(boardString), "placeholder_uart" );
      app.loadByteArray(
               QByteArray(R"JSON(
               {
                   "name": "flash",
                   "periphery": [
                      { "type": "DISPLAY", "name": "1" },
                      { "type": "OUTPUT", "name": "Alarm" },
                      { "type": "INPUT", "name": "TouchInt"}
                    ]
               }
      )JSON" ), "intern" );

      pinmux.setBoardApp(board, app);

      int status=0;
      try
      {
         pinmux.resolveApp( CPinmux::EMethod::linear );
      }
      catch(...)
      {
         status=1;
      }
      REQUIRE ( status == 0);
      CConstructorPool constructors;
      constructors.loadByteArray( QByteArray(boardString), "intern" );
      CWriterPlatform writer(pinmux, constructors, "");
      CPeripheryPtr p=board.findPeripheryByPeripheryName("DISPLAY");

      qWarning("Instance: %s", qPrintable(writer.getInstanceName( *p ) ) );
      qWarning("Arguments: %s", qPrintable(writer.getPeripheralArgumentsString( *p ) ) );

      REQUIRE ( writer.getPeripheralArgumentsString( *p ) == QString("m_display1_spi, eGpioPeripheralA, eGpioPin4") );

      p=board.findPeripheryByPeripheryName("INPUT_PA5");
      qWarning("Instance: %s", qPrintable( writer.getInstanceName( *p ) ) );
      qWarning("Arguments: %s", qPrintable( writer.getPeripheralArgumentsString( *p ) ) );

      REQUIRE (  writer.getPeripheralArgumentsString( *p ) == QString("eGpioPeripheralA, eGpioPin5, extiConfig_EXTI5_input") );
   }

}

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