/* -*- 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_TESTS_UNIT_TESTS_DUMMY_CLIENT_FACE_HPP
#define NDN_TESTS_UNIT_TESTS_DUMMY_CLIENT_FACE_HPP

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/transport/transport.hpp>

namespace chronos {
namespace test {

class DummyClientTransport : public ndn::Transport
{
public:
  void
  receive(const Block& block)
  {
    if (static_cast<bool>(m_receiveCallback))
      m_receiveCallback(block);
  }

  virtual void
  close()
  {
  }

  virtual void
  pause()
  {
  }

  virtual void
  resume()
  {
  }

  virtual void
  send(const Block& wire)
  {
    if (wire.type() == tlv::Interest) {
      m_sentInterests->push_back(Interest(wire));
    }
    else if (wire.type() == tlv::Data) {
      m_sentDatas->push_back(Data(wire));
    }
  }

  virtual void
  send(const Block& header, const Block& payload)
  {
    this->send(payload);
  }

public:
  std::vector<Interest>* m_sentInterests;
  std::vector<Data>*     m_sentDatas;
};


/** \brief a client-side face for unit testing
 */
class DummyClientFace : public ndn::Face
{
public:
  explicit
  DummyClientFace(shared_ptr<DummyClientTransport> transport)
    : Face(transport)
    , m_transport(transport)
  {
    m_transport->m_sentInterests = &m_sentInterests;
    m_transport->m_sentDatas     = &m_sentDatas;
  }

  DummyClientFace(shared_ptr<DummyClientTransport> transport, boost::asio::io_service& ioService)
    : Face(transport, ioService)
    , m_transport(transport)
  {
    m_transport->m_sentInterests = &m_sentInterests;
    m_transport->m_sentDatas     = &m_sentDatas;
  }

  /** \brief cause the Face to receive a packet
   */
  template<typename Packet>
  void
  receive(const Packet& packet)
  {
    m_transport->receive(packet.wireEncode());
  }

public:
  /** \brief sent Interests
   *  \note After .expressInterest, .processEvents must be called before
   *        the Interest would show up here.
   */
  std::vector<Interest> m_sentInterests;
  /** \brief sent Datas
   *  \note After .put, .processEvents must be called before
   *        the Interest would show up here.
   */
  std::vector<Data>     m_sentDatas;

private:
  shared_ptr<DummyClientTransport> m_transport;
};

inline shared_ptr<DummyClientFace>
makeDummyClientFace()
{
  return make_shared<DummyClientFace>(make_shared<DummyClientTransport>());
}

inline shared_ptr<DummyClientFace>
makeDummyClientFace(boost::asio::io_service& ioService)
{
  return make_shared<DummyClientFace>(make_shared<DummyClientTransport>(), ref(ioService));
}

} // namespace tests
} // namespace ndn

#endif // NDN_TESTS_UNIT_TESTS_DUMMY_CLIENT_FACE_HPP
