/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * See COPYING for copyright and distribution information.
 */

#include "management/nfd-control-response.hpp"
#include "management/nfd-fib-management-options.hpp"
#include "management/nfd-face-management-options.hpp"
#include "management/nfd-face-event-notification.hpp"
#include "management/nfd-face-status.hpp"

#include <boost/test/unit_test.hpp>
#include <boost/test/output_test_stream.hpp>

using namespace std;

namespace ndn {
namespace nfd {

BOOST_AUTO_TEST_SUITE(TestNfdControl)

const uint8_t TestControlResponse[] = {0x65, 0x17,
                                         0x66, 0x02, 0x01, 0x94, 0x67, 0x11, 0x4e, 0x6f, 0x74,
                                         0x68, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f, 0x74, 0x20,
                                         0x66, 0x6f, 0x75, 0x6e, 0x64};

const uint8_t TestFibManagementOptions[] = {
  0x68, 0x49, 0x07, 0x16, 0x08, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68,
  0x6f, 0x73, 0x74, 0x08, 0x03, 0x72, 0x65, 0x67, 0x08, 0x04, 0x74, 0x65,
  0x73, 0x74, 0x69, 0x01, 0x00, 0x6a, 0x01, 0x01, 0x6b, 0x29, 0x07, 0x27,
  0x08, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x08,
  0x03, 0x6e, 0x66, 0x64, 0x08, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65,
  0x67, 0x79, 0x08, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2d, 0x77, 0x6f,
  0x72, 0x6c, 0x64
};

const uint8_t TestFaceManagementOptions[] = {
  0x6c, 0x1e, 0x69, 0x01, 0x0a, 0x72, 0x19, 0x74, 0x63, 0x70, 0x3a, 0x2f,
  0x2f, 0x31, 0x2e, 0x31, 0x2e, 0x31, 0x2e, 0x31, 0x2f, 0x68, 0x65, 0x6c,
  0x6c, 0x6f, 0x2f, 0x77, 0x6f, 0x72, 0x6c, 0x64
};

const uint8_t TestFaceEventNotification[] = {
  0xc0, 0x1d, 0xc1, 0x01, 0x01, 0x69, 0x01, 0x64, 0x72, 0x15, 0x74, 0x63,
  0x70, 0x34, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30,
  0x2e, 0x31, 0x3a, 0x36, 0x33, 0x36, 0x33
};

const uint8_t TestFaceStatus[] = {
  0x80, 0x27, 0x69, 0x01, 0x64, 0x72, 0x15, 0x74, 0x63, 0x70, 0x34, 0x3a,
  0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x3a,
  0x36, 0x33, 0x36, 0x33, 0x91, 0x01, 0x0a, 0x90, 0x01, 0x14, 0x92, 0x01,
  0x1e, 0x93, 0x02, 0x01, 0x90
};

// ControlResponse

BOOST_AUTO_TEST_CASE(ControlResponseEncode)
{
  ControlResponse controlResponse(404, "Nothing not found");
  const Block &wire = controlResponse.wireEncode();

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

BOOST_AUTO_TEST_CASE(ControlResponseDecode)
{
  ControlResponse controlResponse;

  BOOST_REQUIRE_NO_THROW(controlResponse.wireDecode(Block(TestControlResponse, sizeof(TestControlResponse))));

  BOOST_REQUIRE_EQUAL(controlResponse.getCode(), 404);
  BOOST_REQUIRE_EQUAL(controlResponse.getText(), "Nothing not found");
}

// FibManagementOptions

BOOST_AUTO_TEST_CASE(FibManagementOptionsEncoding)
{
  Name n("/localhost/reg/test");
  FibManagementOptions opt;

  opt.setName(n);
  opt.setFaceId(0);
  opt.setCost(1);
  opt.setStrategy("/localhost/nfd/strategy/hello-world");

  const Block& blk = opt.wireEncode();

  BOOST_REQUIRE_EQUAL_COLLECTIONS(TestFibManagementOptions,
                                  TestFibManagementOptions + sizeof(TestFibManagementOptions),
                                  blk.begin(), blk.end());
}

BOOST_AUTO_TEST_CASE(FibManagementOptionsFastEncoding)
{
  Name n("/localhost/reg/test");
  FibManagementOptions opt;

  opt.setName(n);
  opt.setFaceId(0);
  opt.setCost(1);
  opt.setStrategy("/localhost/nfd/strategy/hello-world");

  EncodingBuffer blk;

  BOOST_REQUIRE_NO_THROW(opt.wireEncode(blk));

  BOOST_REQUIRE_EQUAL_COLLECTIONS(TestFibManagementOptions,
                                  TestFibManagementOptions + sizeof(TestFibManagementOptions),
                                  blk.begin(), blk.end());

  EncodingBuffer blk2(4);

  BOOST_REQUIRE_NO_THROW(opt.wireEncode(blk2));

  BOOST_REQUIRE_EQUAL_COLLECTIONS(TestFibManagementOptions,
                                  TestFibManagementOptions + sizeof(TestFibManagementOptions),
                                  blk2.begin(), blk2.end());
}

BOOST_AUTO_TEST_CASE(FibManagementOptionsDecoding)
{
  Block blk(TestFibManagementOptions, sizeof(TestFibManagementOptions));
  Name n("/localhost/reg/test");
  FibManagementOptions opt;

  BOOST_REQUIRE_NO_THROW(opt.wireDecode(blk));

  BOOST_CHECK_EQUAL(opt.getName(), n);
  BOOST_CHECK_EQUAL(opt.getFaceId(), 0);
  BOOST_CHECK_EQUAL(opt.getCost(), 1);
  BOOST_CHECK_EQUAL(opt.getStrategy().toUri(), "/localhost/nfd/strategy/hello-world");
}

BOOST_AUTO_TEST_CASE(FaceManagementOptionsFastEncoding)
{
  FaceManagementOptions opt;

  opt.setFaceId(10);
  opt.setUri("tcp://1.1.1.1/hello/world");

  BOOST_REQUIRE_NO_THROW(opt.wireEncode ());

  BOOST_REQUIRE_EQUAL_COLLECTIONS(TestFaceManagementOptions,
                                  TestFaceManagementOptions + sizeof(TestFaceManagementOptions),
                                  opt.wireEncode().begin(), opt.wireEncode().end());
}

BOOST_AUTO_TEST_CASE(FaceManagementOptionsDecoding)
{
  Block blk(TestFaceManagementOptions, sizeof(TestFaceManagementOptions));
  FaceManagementOptions opt;

  BOOST_REQUIRE_NO_THROW(opt.wireDecode(blk));

  BOOST_CHECK_EQUAL(opt.getFaceId(), 10);
  BOOST_CHECK_EQUAL(opt.getUri(), "tcp://1.1.1.1/hello/world");
}


BOOST_AUTO_TEST_CASE(FaceEventNotificationEncodingDecoding)
{
  FaceEventKind expectedKind = FACE_EVENT_CREATED;
  std::string expectedUri("tcp4://127.0.0.1:6363");
  uint64_t expectedFaceId = 100;

  {
    FaceEventNotification faceEvent(expectedKind, expectedFaceId, expectedUri);
    BOOST_REQUIRE_NO_THROW(faceEvent.wireEncode());

    BOOST_REQUIRE_EQUAL_COLLECTIONS(TestFaceEventNotification,
                                    TestFaceEventNotification + sizeof(TestFaceEventNotification),
                                    faceEvent.wireEncode().begin(), faceEvent.wireEncode().end());

    std::ostringstream os;
    os << faceEvent;
    BOOST_CHECK_EQUAL(os.str(), "FaceEventNotification(Kind: created, FaceID: 100, Uri: tcp4://127.0.0.1:6363)");
  }

  {
    Block blk(TestFaceEventNotification, sizeof(TestFaceEventNotification));
    FaceEventNotification faceEvent(blk);

    BOOST_CHECK_EQUAL(faceEvent.getEventKind(), expectedKind);
    BOOST_CHECK_EQUAL(faceEvent.getFaceId(), expectedFaceId);
    BOOST_CHECK_EQUAL(faceEvent.getUri(), expectedUri);
  }
}

BOOST_AUTO_TEST_CASE(FaceStatusEncodingDecoding)
{
  {
    FaceStatus faceStatus(100, "tcp4://127.0.0.1:6363", 10, 20, 30, 400);
    BOOST_REQUIRE_NO_THROW(faceStatus.wireEncode());

    BOOST_CHECK_EQUAL_COLLECTIONS(TestFaceStatus,
                                  TestFaceStatus + sizeof(TestFaceStatus),
                                  faceStatus.wireEncode().begin(), faceStatus.wireEncode().end());

    std::ostringstream os;
    os << faceStatus;
    BOOST_CHECK_EQUAL(os.str(), "FaceStatus(FaceID: 100, Uri: tcp4://127.0.0.1:6363, "
                      "Counters: 10|20|30|400)");
  }

  {
    Block block(TestFaceStatus, sizeof(TestFaceStatus));
    BOOST_REQUIRE_NO_THROW((FaceStatus(block)));

    FaceStatus faceStatus(block);

    BOOST_CHECK_EQUAL(faceStatus.getFaceId(), 100);
    BOOST_CHECK_EQUAL(faceStatus.getUri(), "tcp4://127.0.0.1:6363");

    BOOST_CHECK_EQUAL(faceStatus.getInInterest(),  10);
    BOOST_CHECK_EQUAL(faceStatus.getInData(),      20);
    BOOST_CHECK_EQUAL(faceStatus.getOutInterest(), 30);
    BOOST_CHECK_EQUAL(faceStatus.getOutData(),     400);
  }
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace nfd
} // namespace ndn
