//----------------------------------------------------------------------------
///
/// \file   app.cpp
///
/// \brief  class describing desired periphery of an application
///
/// \date   20180201
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


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


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


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


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

#include <QString>
#include <QJsonArray>
#include <QJsonDocument>
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QDir>

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

#include "app.h"
#include "helpers.h"


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


int CApp::parseJson( const QJsonObject &jsonObject )
{
   QJsonArray jsonArray = jsonObject["periphery"].toArray();
   QJsonArray subArray;

#if 0
   qDebug() << "-----------------------------------";
   qDebug() << "Parse app JSON";
   qDebug() << "App Name: " << jsonObject["name"].toString();
#endif
   name=jsonObject["name"].toString();
   if(id.isEmpty())
      id=jsonObject["id"].toString();
   debugUart=jsonObject["debugUart"].toString();
   symbolMapList=jsonArrayToStringList( jsonObject["symbolMap"].toArray() );
   heartbeat=!jsonObject["heartbeat"].isUndefined();

   for (const auto &value: jsonArray)
   {
      QJsonObject object=value.toObject();

      if( object["status"].toString() == "disabled" )
      {
         continue;
      }

      if( !CVariant(object["variant"].toString()).matches( getVariant() ) )
      {
         continue;
      }

      CReference reference(   object["name"].toString(),
                              object["type"].toString(),
                              object["periphery"].toString());

      if( !reference.parseJSON(object, boardId) )
      {
         continue;
      }

      referenceList+=reference;
   }

   loadProperties(jsonObject);

   jsonArray = jsonObject["symmap"].toArray();
   for(const QJsonValue &value: jsonArray)
   {
      QJsonObject object=value.toObject();
      QString from = object["from"].toString();
      QString to = object["to"].toString();
      SymbolMap[from]=to;
   }

   jsonArray = jsonObject["options"].toArray();
   QStringList list;
   for(const QJsonValue &value: jsonArray)
   {
      list+=value.toString();
   }
   setOptions(list);

   return(0);
}

bool CApp::loadFile(const QString &fileName)
{
   QFile file;
   bool sta=true;

   addPath( QFileInfo( fileName ).dir().path() );

   file.setFileName(fileName);
   if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
   {
      qFatal("Could not open file :%s", qPrintable(fileName));
   }
   sta=loadByteArray( file.readAll(), fileName );
   if( !sta )
   {
      qDebug() << "Parse Error in file " << fileName << ": " ;
   }
   file.close();

   return(sta);
}

bool CApp::loadByteArray(const QByteArray &array, const QString &fileName)
{
    QJsonDocument settdoc;
    QJsonObject jsonObject;
    QJsonParseError error;
    bool sta=true;

    settdoc=QJsonDocument::fromJson(array, &error);
    if(error.error != QJsonParseError::ParseError::NoError )
    {
       qDebug() << "Parse Error in file " << fileName << ": " ;
       qDebug() << error.errorString() << " at offset " << error.offset;
       if(error.offset>40)
       {
          QString line=array.mid(error.offset-40, 80);
          qDebug() << "Line: " << line;
       }
       return(false);
    }
    jsonObject = settdoc.object();

    parseJson(jsonObject);

    return(sta);
}


void CApp::dump() const
{
   qWarning("Dumping App: ");

   for(const auto &reference: referenceList)
   {
      qWarning("   %s: %s, relation '%d', id %d -> %d"
                  , qPrintable(reference.getName())
                  , qPrintable(reference.getPeripheryType())
                  , (int)reference.getRelation()
                  , reference.getId()
                  , reference.getPeripheryLink() ?
                        reference.getPeripheryLink()->getId() : 0
               );
   }
}


void CApp::loadProperties(const QJsonObject &jsonObject)
{
   QVariantMap map = jsonObject["properties"].toObject().toVariantMap();
   // QMap::insert(const QMap&) Qt 5.15
   for( auto key: map.keys())
   {
     m_properties[key]=map[key];
   }

   return;
}

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