#ifndef ROSA_CORE_UNIT_H
#define ROSA_CORE_UNIT_H

#include <atomic>
#include <ostream>
#include <string>

namespace rosa {

// Base class for every entity in the system that has to be identified and
// traced.
class Unit {
private:
  // Number of Units constructed in the system.
  static std::atomic<uint64_t> CountUnits;

  // Number of live units, those having been constructed and not yet destroyed.
  static std::atomic<uint64_t> LiveUnits;

public:
  // System-assigned unique identifier of the Unit instance,
  // based on the static member field CountUnits.
  const uint64_t Id;

  // Textual identifier of the Unit instance. Defaults to a text referring to
  // the Id value of the Unit, unless otherwise defined via a constructor
  // argument. The Name of a Unit is not necessarily unique in the system.
  const std::string Name;

  // Ctor.
  Unit(const std::string &Name = std::string()) noexcept;

  // Dtor.
  virtual ~Unit(void) noexcept;

  // Dumping the object into a string for tracing purposes,
  // subclasses are supposed to override this function.
  virtual std::string dump(void) const noexcept;
};

// Helper function dumping the given Unit instance to the given output stream.
std::ostream &operator<<(std::ostream &os, const Unit &unit);

} // End namespace rosa

#endif // ROSA_CORE_UNIT_H

