/* Blinker
   Copyright 2011-2019 Stefan Schuermans <stefan@blinkenarea.org>
   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
   a blinkenarea.org project */

#include <string>

#include "Directory.h"
#include "File.h"
#include "Module.h"
#include "NameFile.h"
#include "OpSplitter.h"
#include "OpSplitterExtension.h"

namespace Blinker {

/**
 * @brief constructor
 * @param[in] opSplitter owning operator connection splitter object
 * @param[in] name extension name (i.e. phone number)
 * @param[in] dirBase base directory
 */
OpSplitter::Extension::Extension(OpSplitter &opSplitter,
                                 const std::string &name,
                                 const Directory &dirBase):
  m_opSplitter(opSplitter),
  m_name(name),
  m_fileTarget(dirBase.getFile("target"))
{
  // set up
  name2number(m_name, m_number);
  getTarget();
}

/// destructor
OpSplitter::Extension::~Extension()
{
  // remove extension from extension map
  if (m_addedToMap)
    m_opSplitter.m_extMap.erase(m_number);
}

/// check for update of configuration
void OpSplitter::Extension::updateConfig()
{
  // target file was modified -> re-get target operator interface to connect to
  if (m_fileTarget.checkModified())
    getTarget();
}

/// (re-)get target operator interface to connect to
void OpSplitter::Extension::getTarget()
{
  // remove old extension information from extension map
  if (m_addedToMap) {
    m_opSplitter.m_extMap.erase(m_number);
    m_addedToMap = false;
  }

  // get new target operator interface name from file
  m_fileTarget.update();

  // add new module name to extension map
  if (m_fileTarget.m_valid) {
    if (m_opSplitter.m_extMap.find(m_number) == m_opSplitter.m_extMap.end()) {
      m_opSplitter.m_extMap[m_number] = m_fileTarget.m_obj.m_str;
      m_addedToMap = true;
    }
  }
}

/**
 * @brief convert extension name to extension number
 * @param[in] name extension name
 * @param[out] number extension number (name without all non-digits)
 */
void OpSplitter::Extension::name2number(const std::string &name,
                                        std::string &number)
{
  number.clear();
  for (std::string::const_iterator pos = name.begin();
       pos != name.end(); ++pos)
    if (*pos >= '0' && *pos <= '9')
      number += *pos;
}

} // namespace Blinker

