/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2014 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#ifndef NDN_UTIL_SIGNAL_SIGNAL_HPP
#define NDN_UTIL_SIGNAL_SIGNAL_HPP

#include "signal-connection.hpp"
#include <list>

namespace ndn {
namespace util {
namespace signal {

/** \brief provides a lightweight signal / event system
 *
 *  To declare a signal:
 *    public:
 *      Signal<Owner, T1, T2> signalName;
 *  To connect to a signal:
 *    owner->signalName.connect(f);
 *    Multiple functions can connect to the same signal.
 *  To emit a signal from owner:
 *    this->signalName(arg1, arg2);
 *
 *  \tparam Owner the signal owner class; only this class can emit the signal
 *  \tparam TArgs types of signal arguments
 *  \sa signal-emit.hpp allows owner's derived classes to emit signals
 */
template<typename Owner, typename ...TArgs>
class Signal : noncopyable
{
public: // API for anyone
  /** \brief represents a function that can connect to the signal
   */
  typedef function<void(const TArgs&...)> Handler;

  Signal();

  /** \brief connects a handler to the signal
   *  \note If invoked from a handler, the new handler won't receive the current emitted signal.
   *  \warning The handler is permitted to disconnect itself, but it must ensure its validity.
   */
  Connection
  connect(const Handler& handler);

private: // API for owner
  /** \retval true if there is no connection
   */
  bool
  isEmpty() const;

  /** \brief emits a signal
   *  \param args arguments passed to all handlers
   *  \warning Emitting the signal from a handler is undefined behavior.
   *  \note If a handler throws, the exception will be propagated to the caller
   *        who emits this signal, and some handlers may not be executed.
   */
  void
  operator()(const TArgs&...args);

  // make Owner a friend of Signal<Owner, ...> so that API for owner can be called
#if NDN_CXX_HAVE_CXX_FRIEND_TYPENAME
  friend Owner;
#elif NDN_CXX_HAVE_CXX_FRIEND_TYPENAME_WRAPPER
  template<typename T>
  struct TypeWrapper
  {
    typedef T Type;
  }; // http://stackoverflow.com/a/5608542/3729203
  friend class TypeWrapper<Owner>::Type;
#else
#  error "cannot declare Owner as friend"
#endif

private: // internal implementation
  typedef Signal<Owner, TArgs...> Self;
  struct Slot;

  /** \brief stores slots
   *  \note std::list is used because iterators must not be invalidated
   *        when other slots are added or removed
   */
  typedef std::list<Slot> SlotList;

  /** \brief stores a handler function, and a function to disconnect this handler
   */
  struct Slot
  {
    /** \brief the handler function who will receive emitted signals
     */
    Handler handler;

    /** \brief the disconnect function which will disconnect this handler
     *
     *  This is .disconnect method bound with the iterator to this slot.
     *
     *  This is the only shared_ptr to this function object.
     *  Connection class has a weak_ptr which references the same function object.
     *  When the slot is removed or the signal is destructed, this function object would be
     *  destructed, and the related Connections cannot disconnect this slot again.
     */
    shared_ptr<function<void()>> disconnect;
  };

  /** \brief stores slots
   */
  SlotList m_slots;

  /** \brief is a signal handler executing?
   */
  bool m_isExecuting;

  /** \brief iterator to current executing slot
   *  \note This field is meaningful when isExecuting==true
   */
  typename SlotList::iterator m_currentSlot;

  /** \brief disconnects the handler in a slot
   */
  void
  disconnect(typename SlotList::iterator it);
};

template<typename Owner, typename ...TArgs>
Signal<Owner, TArgs...>::Signal()
  : m_isExecuting(false)
{
}

template<typename Owner, typename ...TArgs>
inline Connection
Signal<Owner, TArgs...>::connect(const Handler& handler)
{
  typename SlotList::iterator it = m_slots.insert(m_slots.end(), {handler, nullptr});
  it->disconnect = make_shared<function<void()>>(bind(&Self::disconnect, this, it));

  return signal::Connection(weak_ptr<function<void()>>(it->disconnect));
}

template<typename Owner, typename ...TArgs>
inline void
Signal<Owner, TArgs...>::disconnect(typename SlotList::iterator it)
{
  // it could be const_iterator, but gcc 4.6 doesn't support std::list::erase(const_iterator)

  if (m_isExecuting) {
    // during signal emission, only the currently executing handler can be disconnected
    BOOST_ASSERT_MSG(it == m_currentSlot,
                     "cannot disconnect another handler from a handler");
    m_currentSlot = m_slots.end(); // prevent disconnect twice
  }
  m_slots.erase(it);
}

template<typename Owner, typename ...TArgs>
inline bool
Signal<Owner, TArgs...>::isEmpty() const
{
  return !m_isExecuting && m_slots.empty();
}

template<typename Owner, typename ...TArgs>
inline void
Signal<Owner, TArgs...>::operator()(const TArgs&... args)
{
  BOOST_ASSERT_MSG(!m_isExecuting, "cannot emit signal from a handler");
  if (m_slots.empty()) {
    return;
  }
  m_isExecuting = true;

  typename SlotList::iterator it = m_slots.begin();
  typename SlotList::iterator last = m_slots.end();
  --last;

  try {
    bool isLast = false;
    while (!isLast) {
      m_currentSlot = it;
      isLast = it == last;
      ++it;

      m_currentSlot->handler(args...);
    }
  }
  catch (...) {
    m_isExecuting = false;
    throw;
  }
  m_isExecuting = false;
}

} // namespace signal

// expose as ndn::util::Signal
using signal::Signal;

} // namespace util
} // namespace ndn

#endif // NDN_UTIL_SIGNAL_SIGNAL_HPP
