/* -*- 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/lsdb-status.hpp"

#include "../boost-test.hpp"
#include <boost/mpl/vector.hpp>
#include <boost/lexical_cast.hpp>

namespace nlsr {
namespace tlv {
namespace test {

BOOST_AUTO_TEST_SUITE(TlvTestLsdbStatus)

const uint8_t LsdbStatusData1[] =
{
  // Header
  0x8a, 0x7b,
  // AdjacencyLsa
  0x83, 0x32,
    // LsaInfo
    0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
    0x80, 0x8b, 0x02, 0x27, 0x10,
    // Adjacency
    0x84, 0x1d, 0x07, 0x0c, 0x08, 0x0a, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x63,
    0x79, 0x31, 0x8d, 0x0a, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x63, 0x79, 0x31,
    0x8c, 0x01, 0x80,
  // CoordinateLsa
  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,
  // NameLsa
  0x89, 0x1c,
    // LsaInfo
    0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
    0x80, 0x8b, 0x02, 0x27, 0x10,
    // Name
    0x07, 0x07, 0x08, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x31
};

const uint8_t LsdbStatusData2[] =
{
  // Header
  0x8a, 0x00
};

const uint8_t LsdbStatusData3[] =
{
  // Header
  0x8a, 0x7b,
  // CoordianteLsa
  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,
  // NameLsa
  0x89, 0x1c,
    // LsaInfo
    0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
    0x80, 0x8b, 0x02, 0x27, 0x10,
    // Name
    0x07, 0x07, 0x08, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x31,
  // AdjacencyLsa
  0x83, 0x32,
    // LsaInfo
    0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
    0x80, 0x8B, 0x02, 0x27, 0x10,
    // Adjacency
    0x84, 0x1d, 0x07, 0x0c, 0x08, 0x0a, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x63,
    0x79, 0x31, 0x8d, 0x0a, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x63, 0x79, 0x31,
    0x8c, 0x01, 0x80
};

BOOST_AUTO_TEST_CASE(LsdbStatusEncode1)
{
  LsdbStatus lsdbStatus;

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

  // AdjacencyLsa
  AdjacencyLsa adjacencyLsa;
  adjacencyLsa.setLsaInfo(lsaInfo);

  Adjacency adjacency1;
  adjacency1.setName("adjacency1");
  adjacency1.setUri("adjacency1");
  adjacency1.setCost(128);
  adjacencyLsa.addAdjacency(adjacency1);

  lsdbStatus.addAdjacencyLsa(adjacencyLsa);

  // CoordinateLsa
  CoordinateLsa coordinateLsa;
  coordinateLsa.setLsaInfo(lsaInfo);

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

  lsdbStatus.addCoordinateLsa(coordinateLsa);

  // NameLsa
  NameLsa nameLsa;
  nameLsa.setLsaInfo(lsaInfo);
  nameLsa.addName("name1");

  lsdbStatus.addNameLsa(nameLsa);

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

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

BOOST_AUTO_TEST_CASE(LsdbStatusEncode2)
{
  LsdbStatus lsdbStatus;

  const ndn::Block& wire = lsdbStatus.wireEncode();
  BOOST_REQUIRE_EQUAL_COLLECTIONS(LsdbStatusData2,
                                  LsdbStatusData2 + sizeof(LsdbStatusData2),
                                  wire.begin(), wire.end());
}

BOOST_AUTO_TEST_CASE(LsdbStatusDecode1)
{
  LsdbStatus lsdbStatus;

  lsdbStatus.wireDecode(ndn::Block(LsdbStatusData1, sizeof(LsdbStatusData1)));

  std::list<AdjacencyLsa> adjacencyLsas = lsdbStatus.getAdjacencyLsas();
  std::list<AdjacencyLsa>::const_iterator it1 = adjacencyLsas.begin();

  LsaInfo lsaInfo = it1->getLsaInfo();
  BOOST_CHECK_EQUAL(lsaInfo.getOriginRouter(), "test");
  BOOST_CHECK_EQUAL(lsaInfo.getSequenceNumber(), 128);
  BOOST_CHECK_EQUAL(lsaInfo.getExpirationPeriod(), ndn::time::milliseconds(10000));

  std::list<Adjacency> adjacencies = it1->getAdjacencies();
  std::list<Adjacency>::const_iterator it2 = adjacencies.begin();
  BOOST_CHECK_EQUAL(it2->getName(), "adjacency1");
  BOOST_CHECK_EQUAL(it2->getUri(), "adjacency1");
  BOOST_CHECK_EQUAL(it2->getCost(), 128);

  BOOST_CHECK_EQUAL(lsdbStatus.hasAdjacencyLsas(), true);

  std::list<CoordinateLsa> coordinateLsas = lsdbStatus.getCoordinateLsas();
  std::list<CoordinateLsa>::const_iterator it3 = coordinateLsas.begin();

  lsaInfo = it3->getLsaInfo();
  BOOST_CHECK_EQUAL(lsaInfo.getOriginRouter(), "test");
  BOOST_CHECK_EQUAL(lsaInfo.getSequenceNumber(), 128);
  BOOST_CHECK_EQUAL(lsaInfo.getExpirationPeriod(), ndn::time::milliseconds(10000));

  BOOST_REQUIRE_EQUAL(it3->getHyperbolicRadius(), 1.65);
  std::vector<double> angles;
  angles.push_back(1.78);
  BOOST_REQUIRE(it3->getHyperbolicAngle() == angles);

  BOOST_CHECK_EQUAL(lsdbStatus.hasCoordinateLsas(), true);

  std::list<NameLsa> nameLsas = lsdbStatus.getNameLsas();
  std::list<NameLsa>::const_iterator it4 = nameLsas.begin();

  lsaInfo = it4->getLsaInfo();
  BOOST_CHECK_EQUAL(lsaInfo.getOriginRouter(), "test");
  BOOST_CHECK_EQUAL(lsaInfo.getSequenceNumber(), 128);
  BOOST_CHECK_EQUAL(lsaInfo.getExpirationPeriod(), ndn::time::milliseconds(10000));

  std::list<ndn::Name> names = it4->getNames();
  std::list<ndn::Name>::const_iterator it5 = names.begin();
  BOOST_CHECK_EQUAL(*it5, "name1");

  BOOST_CHECK_EQUAL(lsdbStatus.hasNameLsas(), true);
}

BOOST_AUTO_TEST_CASE(LsdbStatusDecode2)
{
  LsdbStatus lsdbStatus;

  lsdbStatus.wireDecode(ndn::Block(LsdbStatusData2, sizeof(LsdbStatusData2)));

  BOOST_CHECK_EQUAL(lsdbStatus.hasAdjacencyLsas(), false);
  BOOST_CHECK_EQUAL(lsdbStatus.hasCoordinateLsas(), false);
  BOOST_CHECK_EQUAL(lsdbStatus.hasNameLsas(), false);
}

BOOST_AUTO_TEST_CASE(LsdbStatusDecode3)
{
  LsdbStatus lsdbStatus;

  BOOST_CHECK_THROW(lsdbStatus.wireDecode(ndn::Block(LsdbStatusData3, sizeof(LsdbStatusData3))),
                    LsdbStatus::Error);
}

BOOST_AUTO_TEST_CASE(LsdbStatusClear)
{
  LsdbStatus lsdbStatus;

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

  // AdjacencyLsa
  AdjacencyLsa adjacencyLsa;
  adjacencyLsa.setLsaInfo(lsaInfo);

  Adjacency adjacency1;
  adjacency1.setName("adjacency1");
  adjacency1.setUri("adjacency1");
  adjacency1.setCost(128);
  adjacencyLsa.addAdjacency(adjacency1);

  lsdbStatus.addAdjacencyLsa(adjacencyLsa);
  BOOST_CHECK_EQUAL(lsdbStatus.hasAdjacencyLsas(), true);
  lsdbStatus.clearAdjacencyLsas();
  BOOST_CHECK_EQUAL(lsdbStatus.hasAdjacencyLsas(), false);

  // CoordinateLsa
  CoordinateLsa coordinateLsa;
  coordinateLsa.setLsaInfo(lsaInfo);

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

  lsdbStatus.addCoordinateLsa(coordinateLsa);
  BOOST_CHECK_EQUAL(lsdbStatus.hasCoordinateLsas(), true);
  lsdbStatus.clearCoordinateLsas();
  BOOST_CHECK_EQUAL(lsdbStatus.hasCoordinateLsas(), false);

  // NameLsa
  NameLsa nameLsa;
  nameLsa.setLsaInfo(lsaInfo);
  nameLsa.addName("name1");

  lsdbStatus.addNameLsa(nameLsa);
  BOOST_CHECK_EQUAL(lsdbStatus.hasNameLsas(), true);
  lsdbStatus.clearNameLsas();
  BOOST_CHECK_EQUAL(lsdbStatus.hasNameLsas(), false);
}

class Theta
{
public:
  std::vector<double> angles = {1.78};
};

class ThetaAndPhi
{
public:
  std::vector<double> angles = {1.78, 3.21};
};

typedef boost::mpl::vector<Theta, ThetaAndPhi> HyperbolicAngleVectorFixture;

BOOST_AUTO_TEST_CASE_TEMPLATE(LsdbStatusOutputStream, HRAngleVector, HyperbolicAngleVectorFixture)
{
  HRAngleVector angleVector;
  LsdbStatus lsdbStatus;

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

  // AdjacencyLsa
  AdjacencyLsa adjacencyLsa;
  adjacencyLsa.setLsaInfo(lsaInfo);

  Adjacency adjacency1;
  adjacency1.setName("adjacency1");
  adjacency1.setUri("adjacency1");
  adjacency1.setCost(128);
  adjacencyLsa.addAdjacency(adjacency1);

  lsdbStatus.addAdjacencyLsa(adjacencyLsa);

    // NameLsa
  NameLsa nameLsa;
  nameLsa.setLsaInfo(lsaInfo);
  nameLsa.addName("name1");

  lsdbStatus.addNameLsa(nameLsa);

  // CoordinateLsa
  CoordinateLsa coordinateLsa;
  coordinateLsa.setLsaInfo(lsaInfo);

  coordinateLsa.setHyperbolicRadius(1.65);
  coordinateLsa.setHyperbolicAngle(angleVector.angles);

  std::string outputAngles = "HyperbolicAngles: ";
  for (uint i = 0; i < angleVector.angles.size(); i++) {
    std::string angle = boost::lexical_cast<std::string>(angleVector.angles[i]);
    if (i == angleVector.angles.size()-1) {
      outputAngles += angle;
    }
    else {
      outputAngles += angle + ", ";
    }
  }
  outputAngles += "), ";

  lsdbStatus.addCoordinateLsa(coordinateLsa);

  std::ostringstream os;
  os << lsdbStatus;

  BOOST_CHECK_EQUAL(os.str(), "LsdbStatus("
                                "AdjacencyLsa("
                                  "LsaInfo("
                                    "OriginRouter: /test, "
                                    "SequenceNumber: 128, "
                                    "ExpirationPeriod: 10000 milliseconds), "
                                  "Adjacency(Name: /adjacency1, Uri: adjacency1, Cost: 128)), "
                                "CoordinateLsa("
                                  "LsaInfo("
                                    "OriginRouter: /test, "
                                    "SequenceNumber: 128, "
                                    "ExpirationPeriod: 10000 milliseconds), "
                                  "HyperbolicRadius: 1.65, "
                                  + outputAngles +
                                "NameLsa("
                                  "LsaInfo("
                                    "OriginRouter: /test, "
                                    "SequenceNumber: 128, "
                                    "ExpirationPeriod: 10000 milliseconds), "
                                  "Name: /name1))");
}

BOOST_AUTO_TEST_SUITE_END()

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