//----------------------------------------------------------------------------
///
/// \file   writerDot.cpp
///
/// \brief  Generates dot file for graphical overview
///
/// \date   20201211
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


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


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


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


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

#include <QMap>
#include <QFile>
#include <QTextStream>
#include <QSharedPointer>
#include <QProcess>
#include <QDebug>

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

#include "writerDot.h"
#include "board.h"
#include "app.h"

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


int CWriterDot::writeFiles( )
{
   QMap <QString, int> typeCounter;
   QString line;
   QFile file( getBasePath() + "arena.dot");
   if (!file.open(QFile::WriteOnly | QFile::Truncate))
      qFatal("Could not open dot file for writing");
   QTextStream out(&file);

   out << "digraph A {" << "\n";
   out << "   rankdir=LR;\n";
   out << "   concentrate=true;\n";

   out << "\n";

   for(const auto &reference: app().getConstReferenceList() )
   {
      writeReference(out, reference);
   }

   out << "}\n";

   file.close();

   QProcess::execute("dot", { ( getBasePath() + "arena.dot" ),
                 "-Tpng", "-o", ( getBasePath() + "arena.png" ) } );

   return(0);
}

int CWriterDot::writeReference(QTextStream &out, const CReference &reference)
{
   CPeriphery *periphery=reference.getPeripheryLink().data();

   if( periphery->getAttribute( "type" ) == "power" )
   {
      return(0);
   }

   QString referenceName=reference.getPeripheryType() + "_" +  reference.getName();
   out << peripheryConsumesList(referenceName, *periphery );

   out << "\n";
   return(0);
}

QString CWriterDot::peripheryConsumesList(const QString &referenceName, const CPeriphery &periphery) const
{
   QString text;
   int counter=0;
   for(const auto &creference: periphery.getConsumesListConst())
   {
      QString peripheryName;
      if( ! creference.getPeripheryLink()->getPeripheryName().isEmpty())
      {
         if ( creference.getPeripheryLink()->getAttribute( "type" ) == "power" )
         {
            //continue;
         }
         
         // Dont show pseudo periphery unless its explicitly wanted to be shown
         if ( ! creference.getPeripheryLink()->doInstantiateImplementation(true) )
         {
            continue;
         }

         text += "\"" + referenceName + "\" -> ";
         peripheryName=creference.getPeripheryLink()->getPeripheryName();
         peripheryName.replace(".", "_");
         peripheryName.replace("[", "_");
         peripheryName.replace("]", "");
         text += peripheryName;
         text += " [ label = \"" + creference.getName() + "\" ];";
         text += "\n";
         counter++;
      }
      text += peripheryConsumesList( peripheryName, *creference.getPeripheryLink() );
   }

   return(text);
}

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