//===-- deluxe/DeluxeSystemImpl.hpp -----------------------------*- C++ -*-===//
//
//                                 The RoSA Framework
//
// Distributed under the terms and conditions of the Boost Software License 1.0.
// See accompanying file LICENSE.
//
// If you did not receive a copy of the license file, see
// http://www.boost.org/LICENSE_1_0.txt.
//
//===----------------------------------------------------------------------===//
///
/// \file deluxe/DeluxeSystemImpl.hpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017
///
/// \brief Declaration of a basic implementation of the
/// \c rosa::deluxe::DeluxeSystem interface.
///
//===----------------------------------------------------------------------===//

#ifndef ROSA_LIB_DELUXE_DELUXESYSTEMIMPL_HPP
#define ROSA_LIB_DELUXE_DELUXESYSTEMIMPL_HPP

#include "../core/MessagingSystemImpl.hpp"

#include "rosa/deluxe/DeluxeSystem.hpp"

namespace rosa {
namespace deluxe {

/// Implements \c rosa::deluxe::DeluxeSystem by extending
/// \c rosa::MessagingSystemImpl.
class DeluxeSystemImpl : public DeluxeSystem, public MessagingSystemImpl {
  /// Alies for the base-class \c rosa::MessagingSystemImpl.
  using Base = MessagingSystemImpl;

public:
  /// Creates an instance.
  ///
  /// \param Name name of the new instance
  DeluxeSystemImpl(const std::string &Name) noexcept;

  /// \defgroup DeluxeSystemImplCallForwardings Call forwardings of rosa::deluxe::DeluxeSystemImpl
  ///
  /// \c rosa::deluxe::DeluxeSystemImpl call forwardings
  ///
  /// \note Simply forwarding calls to implementations provided by
  /// \c rosa::deluxe::DeluxeSystem::Base for the \c rosa::MessagingSystem
  /// interface.
  ///
  /// \todo How could we use the inherited implementations in a simpler way?
  ///@{

  bool operator==(const System &Other) const noexcept override {
    return Base::operator==(Other);
  }

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

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

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

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

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

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

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

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

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

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

  void send(const AgentHandle &H, message_t &&M) noexcept override {
    Base::send(H, std::move(M));
  }

  ///@}

  /// Tells whether a \c rosa::AgentHandle refers to a
  /// \c rosa::deluxe::DeluxeSensor owned by \p this object.
  ///
  /// \param H \c rosa::AgentHandle to check
  ///
  /// \return whether \p H refers to a \c rosa::deluxe::DeluxeSensor owned by
  /// \p this object
  bool isDeluxeSensor(const AgentHandle &H) const noexcept override;

  /// Tells whether a \c rosa::AgentHandle refers to a
  /// \c rosa::deluxe::DeluxeAgent owned by \p this object.
  ///
  /// \param H \c rosa::AgentHandle to check
  ///
  /// \return whether \p H refers to a \c rosa::deluxe::DeluxeAgent owned by
  /// \p this object
  bool isDeluxeAgent(const AgentHandle &H) const noexcept override;

};

} // End namespace deluxe
} // End namespace rosa

#endif // ROSA_LIB_DELUXE_DELUXESYSTEMIMPL_HPP
