/*******************************************************************************
 *
 * File:     AgentHandle.hpp
 *
 * Contents: Declaration of AgentHandle.
 *
 * Copyright 2017
 *
 * Author: David Juhasz (david.juhasz@tuwien.ac.at)
 *
 ******************************************************************************/

#ifndef ROSA_CORE_AGENTHANDLE_HPP
#define ROSA_CORE_AGENTHANDLE_HPP

#include "rosa/core/AbstractAgent.hpp"

namespace rosa {

// Wraps an actual Agent to decouple its public interface.
// NOTE: Such decoupling might be necessary when operating with remote
// Systems, sometime in the future.
class AgentHandle : public AbstractAgent<AgentHandle> {
  // Agent and MessagingSystem are our friends, they may inspect the
  // private member fields of the class.
  friend class Agent;
  friend class MessagingSystem;

  // The wrapped Agent instance.
  Agent &A;

  // The owning MessagingSystem of A.
  MessagingSystem &S;

  // Ctor used by Agents creating a reference to itself during construction.
  // NOTE: The state of the Agent is not validated by this constructor.
  AgentHandle(Agent &A, bool);

public:
  // Public ctor for normal use.
  // NOTE: The Agent must be in a valid state to create an AgentHandle with.
  // PRE: A.system().isUnitRegistered(A)
  AgentHandle(Agent &A);

  // Dtor, nothing to take care of.
  ~AgentHandle(void) = default;

  // Tells if the AgentHandle is valid, referring to an existing Agent.
  // NOTE: AgentHandlers belong to MessagingSystems. Working with an
  // AgentHandler whose originating MessagingSystem has already been destroyed
  // results in undefined behavior.
  operator bool(void) const noexcept override;

  // Tells if the given reference refers to this Agent.
  bool operator==(const AgentHandle &H) const noexcept override;

  // Returns a reference to this Agent.
  AgentHandle self(void) noexcept override;

  // Sends the given Message to this Agent.
  // PRE: bool(*this)
  void sendMessage(message_t &&M) noexcept override;

};

} // End namespace rosa

#endif // ROSA_CORE_AGENTHANDLE_HPP

