/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2024 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.
 */

#include "ndn-cxx/util/dummy-client-face.hpp"

#include "ndn-cxx/impl/lp-field-tag.hpp"
#include "ndn-cxx/lp/fields.hpp"
#include "ndn-cxx/lp/packet.hpp"
#include "ndn-cxx/lp/tags.hpp"
#include "ndn-cxx/mgmt/nfd/control-parameters.hpp"
#include "ndn-cxx/mgmt/nfd/control-response.hpp"
#include "ndn-cxx/transport/transport.hpp"

#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>

namespace ndn {
namespace {

class DummyTransport final : public ndn::Transport
{
public:
  void
  receive(Block block) const
  {
    block.encode();
    if (m_receiveCallback) {
      m_receiveCallback(block);
    }
  }

  void
  send(const Block& block) final
  {
    onSendBlock(block);
  }

  void
  close() final
  {
  }

  void
  pause() final
  {
  }

  void
  resume() final
  {
  }

public:
  signal::Signal<DummyTransport, Block> onSendBlock;
};

} // namespace

struct DummyClientFace::BroadcastLink
{
  std::vector<DummyClientFace*> faces;
};

DummyClientFace::AlreadyLinkedError::AlreadyLinkedError()
  : Error("Face has already been linked to another face")
{
}

DummyClientFace::DummyClientFace(const Options& options)
  : Face(make_shared<DummyTransport>())
  , m_internalKeyChain(make_unique<KeyChain>())
  , m_keyChain(*m_internalKeyChain)
{
  this->construct(options);
}

DummyClientFace::DummyClientFace(KeyChain& keyChain, const Options& options)
  : Face(make_shared<DummyTransport>(), keyChain)
  , m_keyChain(keyChain)
{
  this->construct(options);
}

DummyClientFace::DummyClientFace(boost::asio::io_context& ioCtx, const Options& options)
  : Face(make_shared<DummyTransport>(), ioCtx)
  , m_internalKeyChain(make_unique<KeyChain>())
  , m_keyChain(*m_internalKeyChain)
{
  this->construct(options);
}

DummyClientFace::DummyClientFace(boost::asio::io_context& ioCtx, KeyChain& keyChain, const Options& options)
  : Face(make_shared<DummyTransport>(), ioCtx, keyChain)
  , m_keyChain(keyChain)
{
  this->construct(options);
}

DummyClientFace::~DummyClientFace()
{
  unlink();
}

void
DummyClientFace::construct(const Options& options)
{
  static_cast<DummyTransport&>(getTransport()).onSendBlock.connect([this] (Block packet) {
    packet.encode();
    lp::Packet lpPacket(packet);
    auto frag = lpPacket.get<lp::FragmentField>();
    Block block({frag.first, frag.second});

    if (block.type() == tlv::Interest) {
      auto interest = make_shared<Interest>(block);
      if (lpPacket.has<lp::NackField>()) {
        auto nack = make_shared<lp::Nack>(std::move(*interest));
        nack->setHeader(lpPacket.get<lp::NackField>());
        addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(*nack, lpPacket);
        onSendNack(*nack);
      }
      else {
        addTagFromField<lp::NextHopFaceIdTag, lp::NextHopFaceIdField>(*interest, lpPacket);
        addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(*interest, lpPacket);
        onSendInterest(*interest);
      }
    }
    else if (block.type() == tlv::Data) {
      auto data = make_shared<Data>(block);
      addTagFromField<lp::CachePolicyTag, lp::CachePolicyField>(*data, lpPacket);
      addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(*data, lpPacket);
      onSendData(*data);
    }
  });

  if (options.enablePacketLogging)
    enablePacketLogging();

  if (options.enableRegistrationReply)
    enableRegistrationReply(options.registrationReplyFaceId);

  m_processEventsOverride = options.processEventsOverride;

  enableBroadcastLink();
}

void
DummyClientFace::enableBroadcastLink()
{
  this->onSendInterest.connect([this] (const Interest& interest) {
      if (m_bcastLink != nullptr) {
        for (auto otherFace : m_bcastLink->faces) {
          if (otherFace != this) {
            otherFace->receive(interest);
          }
        }
      }
    });
  this->onSendData.connect([this] (const Data& data) {
      if (m_bcastLink != nullptr) {
        for (auto otherFace : m_bcastLink->faces) {
          if (otherFace != this) {
            otherFace->receive(data);
          }
        }
      }
    });
  this->onSendNack.connect([this] (const lp::Nack& nack) {
      if (m_bcastLink != nullptr) {
        for (auto otherFace : m_bcastLink->faces) {
          if (otherFace != this) {
            otherFace->receive(nack);
          }
        }
      }
    });
}

void
DummyClientFace::enablePacketLogging()
{
  onSendInterest.connect([this] (const Interest& interest) {
    this->sentInterests.push_back(interest);
  });
  onSendData.connect([this] (const Data& data) {
    this->sentData.push_back(data);
  });
  onSendNack.connect([this] (const lp::Nack& nack) {
    this->sentNacks.push_back(nack);
  });
}

void
DummyClientFace::enableRegistrationReply(uint64_t faceId)
{
  onSendInterest.connect([=] (const Interest& interest) {
    static const Name localhostRibPrefix("/localhost/nfd/rib");
    static const name::Component registerVerb("register");
    const auto& name = interest.getName();
    if (name.size() <= 4 || !localhostRibPrefix.isPrefixOf(name))
      return;

    nfd::ControlParameters params(name[4].blockFromValue());
    if (!params.hasFaceId()) {
      params.setFaceId(faceId);
    }
    if (!params.hasOrigin()) {
      params.setOrigin(nfd::ROUTE_ORIGIN_APP);
    }
    if (!params.hasCost() && name[3] == registerVerb) {
      params.setCost(0);
    }

    nfd::ControlResponse resp;
    resp.setCode(200);
    resp.setBody(params.wireEncode());

    auto data = make_shared<Data>(name);
    data->setContent(resp.wireEncode());
    m_keyChain.sign(*data, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256));
    boost::asio::post(getIoContext(), [this, data] { this->receive(*data); });
  });
}

void
DummyClientFace::receive(const Interest& interest)
{
  lp::Packet lpPacket(interest.wireEncode());

  addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, interest);
  addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest);
  addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest);

  static_cast<DummyTransport&>(getTransport()).receive(lpPacket.wireEncode());
}

void
DummyClientFace::receive(const Data& data)
{
  lp::Packet lpPacket(data.wireEncode());

  addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, data);
  addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);

  static_cast<DummyTransport&>(getTransport()).receive(lpPacket.wireEncode());
}

void
DummyClientFace::receive(const lp::Nack& nack)
{
  lp::Packet lpPacket;
  lpPacket.add<lp::NackField>(nack.getHeader());
  Block interest = nack.getInterest().wireEncode();
  lpPacket.add<lp::FragmentField>({interest.begin(), interest.end()});

  addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, nack);
  addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);

  static_cast<DummyTransport&>(getTransport()).receive(lpPacket.wireEncode());
}

void
DummyClientFace::linkTo(DummyClientFace& other)
{
  if (m_bcastLink != nullptr && other.m_bcastLink != nullptr) {
    if (m_bcastLink != other.m_bcastLink) {
      // already on different links
      NDN_THROW(AlreadyLinkedError());
    }
  }
  else if (m_bcastLink == nullptr && other.m_bcastLink != nullptr) {
    m_bcastLink = other.m_bcastLink;
    m_bcastLink->faces.push_back(this);
  }
  else if (m_bcastLink != nullptr && other.m_bcastLink == nullptr) {
    other.m_bcastLink = m_bcastLink;
    m_bcastLink->faces.push_back(&other);
  }
  else {
    m_bcastLink = other.m_bcastLink = make_shared<BroadcastLink>();
    m_bcastLink->faces.push_back(this);
    m_bcastLink->faces.push_back(&other);
  }
}

void
DummyClientFace::unlink()
{
  if (m_bcastLink == nullptr) {
    return;
  }

  auto it = std::find(m_bcastLink->faces.begin(), m_bcastLink->faces.end(), this);
  BOOST_ASSERT(it != m_bcastLink->faces.end());
  m_bcastLink->faces.erase(it);

  if (m_bcastLink->faces.size() == 1) {
    m_bcastLink->faces[0]->m_bcastLink = nullptr;
    m_bcastLink->faces.clear();
  }
  m_bcastLink = nullptr;
}

void
DummyClientFace::doProcessEvents(time::milliseconds timeout, bool keepRunning)
{
  if (m_processEventsOverride != nullptr) {
    m_processEventsOverride(timeout);
  }
  else {
    Face::doProcessEvents(timeout, keepRunning);
  }
}

} // namespace ndn
