/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2023,  The University of Memphis,
 *                           Regents of the University of California,
 *                           Arizona Board of Regents.
 *
 * This file is part of NLSR (Named-data Link State Routing).
 * See AUTHORS.md for complete list of NLSR authors and contributors.
 *
 * NLSR is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NLSR 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "coordinate-lsa.hpp"
#include "tlv-nlsr.hpp"

namespace nlsr {

CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
                             const ndn::time::system_clock::time_point& timepoint,
                             double radius, std::vector<double> angles)
  : Lsa(originRouter, seqNo, timepoint)
  , m_hyperbolicRadius(radius)
  , m_hyperbolicAngles(angles)
{
}

CoordinateLsa::CoordinateLsa(const ndn::Block& block)
{
  wireDecode(block);
}

bool
CoordinateLsa::isEqualContent(const CoordinateLsa& clsa) const
{
  if (clsa.getCorTheta().size() != m_hyperbolicAngles.size()) {
    return false;
  }

  std::vector<double> m_angles2 = clsa.getCorTheta();
  for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
    if (std::abs(m_hyperbolicAngles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
      return false;
    }
  }

  return (std::abs(m_hyperbolicRadius - clsa.getCorRadius()) <
          std::numeric_limits<double>::epsilon());
}

template<ndn::encoding::Tag TAG>
size_t
CoordinateLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
{
  size_t totalLength = 0;

  for (auto it = m_hyperbolicAngles.rbegin(); it != m_hyperbolicAngles.rend(); ++it) {
    totalLength += ndn::encoding::prependDoubleBlock(block, nlsr::tlv::HyperbolicAngle, *it);
  }

  totalLength += ndn::encoding::prependDoubleBlock(block, nlsr::tlv::HyperbolicRadius, m_hyperbolicRadius);

  totalLength += Lsa::wireEncode(block);

  totalLength += block.prependVarNumber(totalLength);
  totalLength += block.prependVarNumber(nlsr::tlv::CoordinateLsa);

  return totalLength;
}

NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);

const ndn::Block&
CoordinateLsa::wireEncode() const
{
  if (m_wire.hasWire()) {
    return m_wire;
  }

  ndn::EncodingEstimator estimator;
  size_t estimatedSize = wireEncode(estimator);

  ndn::EncodingBuffer buffer(estimatedSize, 0);
  wireEncode(buffer);

  m_wire = buffer.block();

  return m_wire;
}

void
CoordinateLsa::wireDecode(const ndn::Block& wire)
{
  m_wire = wire;

  if (m_wire.type() != nlsr::tlv::CoordinateLsa) {
    NDN_THROW(Error("CoordinateLsa", m_wire.type()));
  }

  m_wire.parse();

  auto val = m_wire.elements_begin();

  if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Lsa) {
    Lsa::wireDecode(*val);
    ++val;
  }
  else {
    NDN_THROW(Error("Missing required Lsa field"));
  }

  if (val != m_wire.elements_end() && val->type() == nlsr::tlv::HyperbolicRadius) {
    m_hyperbolicRadius = ndn::encoding::readDouble(*val);
    ++val;
  }
  else {
    NDN_THROW(Error("Missing required HyperbolicRadius field"));
  }

  std::vector<double> angles;
  for (; val != m_wire.elements_end(); ++val) {
    if (val->type() == nlsr::tlv::HyperbolicAngle) {
      angles.push_back(ndn::encoding::readDouble(*val));
    }
    else {
      NDN_THROW(Error("Missing required HyperbolicAngle field"));
    }
  }
  m_hyperbolicAngles = angles;
}

std::string
CoordinateLsa::toString() const
{
  std::ostringstream os;
  os << getString();
  os << "      Hyperbolic Radius  : " << m_hyperbolicRadius << "\n";
  int i = 0;
  for (const auto& value : m_hyperbolicAngles) {
    os << "      Hyperbolic Theta " << i++ << " : " << value << "\n";
  }

  return os.str();
}

std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
CoordinateLsa::update(const std::shared_ptr<Lsa>& lsa)
{
  auto clsa = std::static_pointer_cast<CoordinateLsa>(lsa);
  if (!isEqualContent(*clsa)) {
    m_hyperbolicRadius = clsa->getCorRadius();
    m_hyperbolicAngles.clear();
    for (const auto& angle : clsa->getCorTheta()) {
      m_hyperbolicAngles.push_back(angle);
    }
    return {true, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
  }
  return {false, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
}

std::ostream&
operator<<(std::ostream& os, const CoordinateLsa& lsa)
{
  return os << lsa.toString();
}

} // namespace nlsr
