/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2019,  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 "tlv/coordinate-lsa.hpp"

#include "tests/boost-test.hpp"

namespace nlsr {
namespace tlv {
namespace test {

BOOST_AUTO_TEST_SUITE(TlvTestCoordinateLsa)

const uint8_t CoordinateLsaData[] =
{
  // Header
  0x85, 0x27,
  // LsaInfo
  0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
  0x80, 0x8b, 0x02, 0x27, 0x10,
  // HyperbolicRadius
  0x87, 0x08, 0x3f, 0xfa, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
  // HyperbolicAngle
  0x88, 0x08, 0x3f, 0xfc, 0x7a, 0xe1, 0x47, 0xae, 0x14, 0x7b

};

BOOST_AUTO_TEST_CASE(CoordinateLsaEncode)
{
  CoordinateLsa coordinateLsa;

  LsaInfo lsaInfo;
  lsaInfo.setOriginRouter("test");
  lsaInfo.setSequenceNumber(128);
  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
  coordinateLsa.setLsaInfo(lsaInfo);

  coordinateLsa.setHyperbolicRadius(1.65);
  std::vector<double> angles;
  angles.push_back(1.78);
  coordinateLsa.setHyperbolicAngle(angles);

  const ndn::Block& wire = coordinateLsa.wireEncode();

  BOOST_REQUIRE_EQUAL_COLLECTIONS(CoordinateLsaData,
                                  CoordinateLsaData + sizeof(CoordinateLsaData),
                                  wire.begin(), wire.end());
}

BOOST_AUTO_TEST_CASE(CoordinateLsaDecode)
{
  CoordinateLsa coordinateLsa;

  coordinateLsa.wireDecode(ndn::Block(CoordinateLsaData, sizeof(CoordinateLsaData)));

  BOOST_REQUIRE_EQUAL(coordinateLsa.getLsaInfo().getOriginRouter(), "test");
  BOOST_REQUIRE_EQUAL(coordinateLsa.getLsaInfo().getSequenceNumber(), 128);
  BOOST_REQUIRE_EQUAL(coordinateLsa.getLsaInfo().getExpirationPeriod(),
                      ndn::time::milliseconds(10000));
  BOOST_REQUIRE_EQUAL(coordinateLsa.getHyperbolicRadius(), 1.65);
  std::vector<double> angles = {1.78};
  BOOST_REQUIRE(coordinateLsa.getHyperbolicAngle() == angles);
}

BOOST_AUTO_TEST_CASE(CoordinateLsaOutputStream)
{
  CoordinateLsa coordinateLsa;

  LsaInfo lsaInfo;
  lsaInfo.setOriginRouter("test");
  lsaInfo.setSequenceNumber(128);
  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
  coordinateLsa.setLsaInfo(lsaInfo);

  coordinateLsa.setHyperbolicRadius(1.65);
  std::vector<double> angles = {1.78};
  coordinateLsa.setHyperbolicAngle(angles);

  std::ostringstream os;
  os << coordinateLsa;

  BOOST_CHECK_EQUAL(os.str(), "CoordinateLsa("
                                "LsaInfo(OriginRouter: /test, "
                                        "SequenceNumber: 128, "
                                        "ExpirationPeriod: 10000 milliseconds), "
                                "HyperbolicRadius: 1.65, "
                                "HyperbolicAngles: 1.78)");

  angles.push_back(3.21);
  coordinateLsa.setHyperbolicAngle(angles);

  std::ostringstream os2;
  os2 << coordinateLsa;

  BOOST_CHECK_EQUAL(os2.str(), "CoordinateLsa("
                                "LsaInfo(OriginRouter: /test, "
                                        "SequenceNumber: 128, "
                                        "ExpirationPeriod: 10000 milliseconds), "
                                "HyperbolicRadius: 1.65, "
                                "HyperbolicAngles: 1.78, 3.21)");
}


BOOST_AUTO_TEST_SUITE_END()

} // namespace test
} // namespace tlv
} // namespace nlsr
