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

#ifndef BLINKER_SYNCRECEIVER_H
#define BLINKER_SYNCRECEIVER_H

#include <string>

#include "Directory.h"
#include "File.h"
#include "IoCallee.h"
#include "Mgrs.h"
#include "Module.h"
#include "OutSyncFile.h"
#include "Protocol.h"
#include "ProtocolFile.h"
#include "SettingFile.h"

namespace Blinker {

/// stream receiver
template<typename ADDR, typename SOCK>
class SyncReceiver: public IoCallee, public Module
{
protected:
  /// type for address setting file
  typedef SettingFile<ADDR> AddrFile;

public:
  /**
   * @brief constructor
   * @param[in] name module name
   * @param[in] mgrs managers
   * @param[in] dirBase base directory
   */
  SyncReceiver(const std::string &name, Mgrs &mgrs, const Directory &dirBase);

  /// virtual destructor
  virtual ~SyncReceiver();

private:
  /// copy constructor disabled
  SyncReceiver(const SyncReceiver &that);

  /// assignment operator disabled
  const SyncReceiver & operator=(const SyncReceiver &that);

public:
  /// check for update of configuration
  virtual void updateConfig();

  /**
   * @brief callback when I/O object is readable
   * @param[in] io I/O object that is readable
   */
  virtual void ioReadCall(Io *io);

  /**
   * @brief callback when I/O object is writable
   * @param[in] io I/O object that is writable
   */
  virtual void ioWriteCall(Io *io);

protected:
  /// create socket and bind it
  void createSock();

  /// destroy socket
  void destroySock();

  /// receive data from socket
  void receiveFromSock();

  /**
   * @brief process synchronization information
   * @param[in] data received synchronization data
   */
  void procInfo(const std::string &data);

protected:
  OutSyncFile m_fileOutSync; ///< output sync stream name file
  AddrFile    m_fileBind;    ///< bind address file
  AddrFile    m_fileSrc;     ///< source address file
  SOCK        *m_pSock;      ///< socket to use for receiving sync stream
}; // class SyncReceiver

} // namespace Blinker

#endif // #ifndef BLINKER_SYNCRECEIVER_H

