/*******************************************************************************
 *
 * File:     MessagingSystemImpl.hpp
 *
 * Contents: Declaration of a basic implementation of the MessagingSystem
 *           interface.
 *
 * Copyright 2017
 *
 * Author: David Juhasz (david.juhasz@tuwien.ac.at)
 *
 ******************************************************************************/

#ifndef ROSA_LIB_CORE_MESSAGINGSYSTEMIMPL_HPP // NOLINT
#define ROSA_LIB_CORE_MESSAGINGSYSTEMIMPL_HPP

#include "SystemImpl.hpp"

#include "rosa/core/MessagingSystem.hpp"

namespace rosa {

// Implements MessagingSystem by extending SystemImpl by adding a
// simple implementation of Message sending: directly invoking the Agent with
// the given Message.
// NOTE: Keep in mind that sending a Message with this implementation
// translates into a direct function call.
class MessagingSystemImpl : public MessagingSystem, public SystemImpl {
  // Referring to SystemImpl as Base inside the class.
  using Base = SystemImpl;

public:
  // Ctor.
  MessagingSystemImpl(const std::string &Name) noexcept;

protected:
  // NOTE: Simply forwarding calls to implementations from Base for the System
  // interface.
  // FIXME: How could we use the inherited implementations in a simpler way?

  inline id_t nextId(void) noexcept override { return Base::nextId(); }

  inline bool isSystemCleaned(void) const noexcept override {
    return Base::isSystemCleaned();
  }

  inline void markCleaned(void) noexcept override { Base::markCleaned(); }

  inline void registerUnit(Unit &U) noexcept override { Base::registerUnit(U); }

  inline void destroyUnit(Unit &U) noexcept override { Base::destroyUnit(U); }

  inline bool isUnitRegistered(const Unit &U) const noexcept override {
    return Base::isUnitRegistered(U);
  }

public:
  inline const std::string &name(void) const noexcept override {
    return Base::name();
  }

  inline size_t numberOfConstructedUnits(void) const noexcept override {
    return Base::numberOfConstructedUnits();
  }

  inline size_t numberOfLiveUnits(void) const noexcept override {
    return Base::numberOfLiveUnits();
  }

  inline bool empty(void) const noexcept override { return Base::empty(); }

  // Directly invokes the Agent with the Message.
  // PRE: &unwrapSystem(H) == this && isUnitRegistered(unwrapAgent(H))
  void send(const AgentHandle &H, message_t &&M) noexcept override;
};

} // End namespace rosa

#endif // ROSA_LIB_CORE_MESSAGINGSYSTEMIMPL_HPP

