//----------------------------------------------------------------------------
///
/// \file   writerCMake.cpp
///
/// \brief  writes cmake script file with board properties
///
///         If the existing file does not differ from the new one, the file
///         is not touched at all.
///         This will prevent cmake to go crazy when the file keeps being
///         touched. So the unchanged-logic does not have to be implemented in
///         the CMake-Scripts.
///
/// \date   20210813
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


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


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


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


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

#include <QFile>
#include <QDebug>

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

#include "writerCMake.h"
#include "board.h"
#include "app.h"

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


CWriterCMake::CWriterCMake(CPinmux &pinmux, const QString &basePath)
   :CWriter(pinmux, basePath)
{
   /*
   QFile file( getBasePath() + "/arena_generated.cmake");
   if( ! getBasePath().isEmpty() )
   {
      file.remove();
      //qWarning() << ">>> remove: " << ( getBasePath() + "/arena_generated.cmake") ;
   }
   */
   return;
}


int CWriterCMake::writeFiles() /* virtual override */
{
   return(0);
}

int CWriterCMake::writeCMake( const CConstructorPool &constructors )
{
   // Write to an seperate file. Check later in checkUpdate() if we have to
   // touch the original file.
   QFile file( getBasePath() + "/arena_generated.cmake" + ".new" );
   if (!file.open(QFile::WriteOnly | QFile::Truncate))
   {
      qFatal("Could not open header file for writing: %s", qPrintable( getBasePath() + "/arena_generated.cmake" + ".new" ));
   }
   QTextStream out(&file);
   const char *category="cmake.";

   out << "#----------------------------------------------------------------------------\n";
   out << "#- File generated by arenas pinmux tool. Don't change it!\n";
   out << "#----------------------------------------------------------------------------\n";
   out << "\n";

   out << "# Number of total properties: " << board().getProperties().count() << "\n";
   out << "\n";

   QVariantMap properties;
   #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
      properties.unite( board().getProperties() );
      properties.unite( app().getProperties() );
   #else
      properties.insert( board().getProperties() );
      properties.insert( app().getProperties() );
   #endif
   
   if ( properties.count() )
   {
      for( auto property: properties.keys() )
      {
         if( property.startsWith( category ) )
         {
            QString _property=property;
            _property.remove(0, strlen( category ) );

            out << "set ( " << _property << " \"" << properties.value(property).toString() << "\" )";
            out << "\n";
         }
      }
   }
   category="defines.";
   QString defines;
   if ( properties.count() )
   {
      for( auto property: properties.keys() )
      {
         if( property.startsWith( category ) )
         {
            QString _property=property;
            _property.remove(0, strlen( category ) );
            // "=\""
            defines += " -D" + _property + "=" + properties.value(property).toString() + "";
         }
      }
   }

   for ( const auto &option: app().getOptions() )
   {
      defines += " -D" + constructors.getFrameWork().toUpper()
               + "_" + option.toUpper();
   }

   out << "add_definitions ( " << defines << " )";
   out << "\n";

   out << "\n";
   out << "#---fin----------------------------------------------------------------------";
   out << "\n";
   file.close();

   checkUpdate();

   return(0);
}


void CWriterCMake::checkUpdate( )
{
   QString fileName=getBasePath() + "/arena_generated.cmake";
   QFile oldFile( fileName );
   QFile newFile( fileName + ".new");
   QByteArray bufOld;
   QByteArray bufNew;
   bool force=false;

   if (!oldFile.open(QFile::ReadOnly))
   {
      force=true;
   }
   else
   {
      bufOld=oldFile.readAll();
      oldFile.close();
   }

   if (!newFile.open(QFile::ReadOnly))
   {
      force=true;
   }
   else
   {
      bufNew=newFile.readAll();
      newFile.close();
   }

   if( force || ( bufNew != bufOld ) )
   {
      qWarning("### Differ; renaming");
      QFile file(fileName + ".new");
      oldFile.remove();
      bool sta=file.rename(fileName);
      if(!sta)
      {
         qCritical("Could not rename cmake file");
      }
   }
   else
   {
      // qWarning("### Not Differ; remaining");
   }

}


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