#include "Processor.h"
#include <sstream>
#include <iostream>

#include "Logger/Logger.h"

#include "TriggerCommandsGUI/TriggerCommands.h"
#include "TriggerCommandsOffLine/TriggerCommands.h"

using namespace std;
using namespace boost;

namespace UpperTestAdapter {
  
namespace Processors {
  
Processor::Processor()
{
}

Processor::~Processor()
{
  m_impl.reset();
}

void Processor::SetImplMode(TriggerCommandsStrategy::Strategies strategy)
{
  if (m_impl.get() == NULL)
  {
    if (strategy == TriggerCommandsStrategy::UEUserGuide)
    {
      Logger::Instance().LogInfo("Processor::SetImplMode: UEUserGuide");
      m_impl.reset(new TriggerCommandsGUI::TriggerCommands);
    }
    else
    {
      Logger::Instance().LogInfo("Processor::SetImplMode: UEOffLine");
      m_impl.reset(new TriggerCommandsOffLine::TriggerCommands);
    }
  }
  else
  {
    Logger::Instance().LogInfo("Processor::SetImplMode: m_impl.get() is not NULL");
  }
}

void Processor::SetEutIpInterface(boost::shared_ptr<EutIPInterface> eutIface)
{
  stringstream ss;
  ss << "Processor::SetEutIpInterface: " << eutIface.get()->Eut();
  Logger::Instance().LogInfo(ss.str());
  
  m_impl.get()->SetEutIpInterface(eutIface);
}

int Processor::Process(const std::string &trigger, const std::vector<std::string> &parameterList)
{
  if (m_impl.get() != NULL)
  {
    return m_impl.get()->Process(trigger, parameterList);
  }
  else
  {
    Logger::Instance().LogError("Processor::Process: pointer uvalue is NULL");
    return 1;
  }
}

/*bool Processor::BeginProcess(const std::string &trigger, const std::vector<std::string> &parameterList)
{
  clog << "Processor::BeginProcess: " << trigger << endl;
  
  // Initialize internal fields.
  m_trigger = trigger;
  m_parameterList = parameterList;
  clog << "Processor::BeginProcess: Internals: " << m_trigger << " - " << m_parameterList.size() << endl;
  m_asyncProcessing = boost::shared_ptr<boost::thread>(new thread(&Processor::InvokeProcess));

  return true;
}

bool Processor::ProcessCompleted()
{
  return false;
}

bool Processor::Wait(int timeout)
{
  if (timeout < 0)
  {
    m_asyncProcessing.get()->join();
  }
  else
  {
    // TODO: make a join with timeout
  }

  return true;
}

void Processor::InvokeProcess()
{
  //clog << "Processor::InvokeProcess: Internals: " << Processor::pThis->m_trigger << " - " << Processor::pThis->m_parameterList.size() << endl;
  //Processor::pThis->m_impl.get()->ProcessTriggerCommand(Processor::pThis->m_trigger, Processor::pThis->m_parameterList);
}*/

} } // namespaces

