/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2014 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 "face.hpp"
#include "util/scheduler.hpp"
#include "security/key-chain.hpp"

#include "identity-management-fixture.hpp"
#include "boost-test.hpp"

namespace ndn {
namespace tests {

class FacesFixture : public security::IdentityManagementFixture
{
public:
  FacesFixture()
    : nData(0)
    , nTimeouts(0)
    , regPrefixId(0)
    , nInInterests(0)
    , nInInterests2(0)
    , nRegFailures(0)
  {
  }

  void
  onData()
  {
    ++nData;
  }

  void
  onTimeout()
  {
    ++nTimeouts;
  }

  void
  onInterest(Face& face,
             const Name&, const Interest&)
  {
    ++nInInterests;

    face.unsetInterestFilter(regPrefixId);
  }

  void
  onInterest2(Face& face,
              const Name&, const Interest&)
  {
    ++nInInterests2;

    face.unsetInterestFilter(regPrefixId2);
  }

  void
  onInterestRegex(Face& face,
                  const InterestFilter&, const Interest&)
  {
    ++nInInterests;
  }

  void
  onInterestRegexError(Face& face,
                       const Name&, const Interest&)
  {
    BOOST_FAIL("InterestFilter::Error should have been triggered");
  }

  void
  onRegFailed()
  {
    ++nRegFailures;
  }

  void
  expressInterest(Face& face, const Name& name)
  {
    Interest i(name);
    i.setInterestLifetime(time::milliseconds(50));
    face.expressInterest(i,
                         bind(&FacesFixture::onData, this),
                         bind(&FacesFixture::onTimeout, this));
  }

  void
  terminate(Face& face)
  {
    face.shutdown();
  }

  uint32_t nData;
  uint32_t nTimeouts;

  const RegisteredPrefixId* regPrefixId;
  const RegisteredPrefixId* regPrefixId2;
  uint32_t nInInterests;
  uint32_t nInInterests2;
  uint32_t nRegFailures;
};

BOOST_FIXTURE_TEST_SUITE(TestFaces, FacesFixture)

BOOST_AUTO_TEST_CASE(Unix)
{
  Face face;

  face.expressInterest(Interest("/", time::milliseconds(1000)),
                       bind(&FacesFixture::onData, this),
                       bind(&FacesFixture::onTimeout, this));

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nData, 1);
  BOOST_CHECK_EQUAL(nTimeouts, 0);

  face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere",
                                time::milliseconds(50)),
                       bind(&FacesFixture::onData, this),
                       bind(&FacesFixture::onTimeout, this));

  Name veryLongName;
  for (size_t i = 0; i <= MAX_NDN_PACKET_SIZE / 10; i++)
    {
      veryLongName.append("0123456789");
    }

  BOOST_CHECK_THROW(face.expressInterest(veryLongName, OnData(), OnTimeout()), Face::Error);

  shared_ptr<Data> data = make_shared<Data>(veryLongName);
  data->setContent(reinterpret_cast<const uint8_t*>("01234567890"), 10);
  m_keyChain.sign(*data);
  BOOST_CHECK_THROW(face.put(*data), Face::Error);

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nData, 1);
  BOOST_CHECK_EQUAL(nTimeouts, 1);
}

BOOST_AUTO_TEST_CASE(Tcp)
{
  Face face("localhost");

  face.expressInterest(Interest("/", time::milliseconds(1000)),
                       bind(&FacesFixture::onData, this),
                       bind(&FacesFixture::onTimeout, this));

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nData, 1);
  BOOST_CHECK_EQUAL(nTimeouts, 0);

  face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere",
                                time::milliseconds(50)),
                       bind(&FacesFixture::onData, this),
                       bind(&FacesFixture::onTimeout, this));

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nData, 1);
  BOOST_CHECK_EQUAL(nTimeouts, 1);
}


BOOST_AUTO_TEST_CASE(SetFilter)
{
  Face face;
  Face face2(face.getIoService());
  Scheduler scheduler(face.getIoService());
  scheduler.scheduleEvent(time::milliseconds(300),
                          bind(&FacesFixture::terminate, this, ref(face)));

  regPrefixId = face.setInterestFilter("/Hello/World",
                                       bind(&FacesFixture::onInterest, this, ref(face), _1, _2),
                                       RegisterPrefixSuccessCallback(),
                                       bind(&FacesFixture::onRegFailed, this));

  scheduler.scheduleEvent(time::milliseconds(200),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/!")));

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nRegFailures, 0);
  BOOST_CHECK_EQUAL(nInInterests, 1);
  BOOST_CHECK_EQUAL(nTimeouts, 1);
  BOOST_CHECK_EQUAL(nData, 0);
}

BOOST_AUTO_TEST_CASE(SetTwoFilters)
{
  Face face;
  Face face2(face.getIoService());
  Scheduler scheduler(face.getIoService());
  scheduler.scheduleEvent(time::seconds(1),
                          bind(&FacesFixture::terminate, this, ref(face)));

  regPrefixId = face.setInterestFilter("/Hello/World",
                                       bind(&FacesFixture::onInterest, this, ref(face), _1, _2),
                                       RegisterPrefixSuccessCallback(),
                                       bind(&FacesFixture::onRegFailed, this));

  regPrefixId2 = face.setInterestFilter("/Los/Angeles/Lakers",
                                        bind(&FacesFixture::onInterest2, this, ref(face), _1, _2),
                                        RegisterPrefixSuccessCallback(),
                                        bind(&FacesFixture::onRegFailed, this));


  scheduler.scheduleEvent(time::milliseconds(200),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/!")));

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nRegFailures, 0);
  BOOST_CHECK_EQUAL(nInInterests, 1);
  BOOST_CHECK_EQUAL(nInInterests2, 0);
  BOOST_CHECK_EQUAL(nTimeouts, 1);
  BOOST_CHECK_EQUAL(nData, 0);
}

BOOST_AUTO_TEST_CASE(SetRegexFilterError)
{
  Face face;
  Face face2(face.getIoService());
  Scheduler scheduler(face.getIoService());
  scheduler.scheduleEvent(time::seconds(1),
                          bind(&FacesFixture::terminate, this, ref(face)));

  regPrefixId = face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
                                       bind(&FacesFixture::onInterestRegexError, this,
                                            ref(face), _1, _2),
                                       RegisterPrefixSuccessCallback(),
                                       bind(&FacesFixture::onRegFailed, this));

  scheduler.scheduleEvent(time::milliseconds(300),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/XXX/b/c"))); // should match

  BOOST_REQUIRE_THROW(face.processEvents(), InterestFilter::Error);
}

BOOST_AUTO_TEST_CASE(SetRegexFilter)
{
  Face face;
  Face face2(face.getIoService());
  Scheduler scheduler(face.getIoService());
  scheduler.scheduleEvent(time::seconds(2),
                          bind(&FacesFixture::terminate, this, ref(face)));

  regPrefixId = face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
                                       bind(&FacesFixture::onInterestRegex, this,
                                            ref(face), _1, _2),
                                       RegisterPrefixSuccessCallback(),
                                       bind(&FacesFixture::onRegFailed, this));

  scheduler.scheduleEvent(time::milliseconds(200),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a"))); // shouldn't match

  scheduler.scheduleEvent(time::milliseconds(300),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a/b"))); // should match

  scheduler.scheduleEvent(time::milliseconds(400),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a/b/c"))); // should match

  scheduler.scheduleEvent(time::milliseconds(500),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a/b/d"))); // should not match

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nRegFailures, 0);
  BOOST_CHECK_EQUAL(nInInterests, 2);
  BOOST_CHECK_EQUAL(nTimeouts, 4);
  BOOST_CHECK_EQUAL(nData, 0);
}

class FacesFixture2 : public FacesFixture
{
public:
  void
  checkPrefix(bool doesExist)
  {
    int result = std::system("nfd-status | grep /Hello/World >/dev/null");

    if (doesExist) {
      BOOST_CHECK_EQUAL(result, 0);
    }
    else {
      BOOST_CHECK_NE(result, 0);
    }
  }
};

BOOST_FIXTURE_TEST_CASE(RegisterUnregisterPrefix, FacesFixture2)
{
  Face face;
  Scheduler scheduler(face.getIoService());
  scheduler.scheduleEvent(time::seconds(2),
                          bind(&FacesFixture::terminate, this, ref(face)));

  regPrefixId = face.setInterestFilter(InterestFilter("/Hello/World"),
                                       bind(&FacesFixture::onInterest, this,
                                            ref(face), _1, _2),
                                       RegisterPrefixSuccessCallback(),
                                       bind(&FacesFixture::onRegFailed, this));

  scheduler.scheduleEvent(time::milliseconds(500),
                          bind(&FacesFixture2::checkPrefix, this, true));

  scheduler.scheduleEvent(time::seconds(1),
    bind(static_cast<void(Face::*)(const RegisteredPrefixId*)>(&Face::unsetInterestFilter),
         &face,
    regPrefixId)); // shouldn't match

  scheduler.scheduleEvent(time::milliseconds(1500),
                          bind(&FacesFixture2::checkPrefix, this, false));

  BOOST_REQUIRE_NO_THROW(face.processEvents());
}


class FacesFixture3 : public FacesFixture2
{
public:
  FacesFixture3()
    : nRegSuccesses(0)
    , nUnregSuccesses(0)
    , nUnregFailures(0)
  {
  }

  void
  onRegSucceeded()
  {
    ++nRegSuccesses;
  }

  void
  onUnregSucceeded()
  {
    ++nUnregSuccesses;
  }

  void
  onUnregFailed()
  {
    ++nUnregFailures;
  }

public:
  uint64_t nRegSuccesses;
  uint64_t nUnregSuccesses;
  uint64_t nUnregFailures;
};

BOOST_FIXTURE_TEST_CASE(RegisterPrefix, FacesFixture3)
{
  Face face;
  Face face2(face.getIoService());
  Scheduler scheduler(face.getIoService());
  scheduler.scheduleEvent(time::seconds(2),
                          bind(&FacesFixture::terminate, this, ref(face)));

  scheduler.scheduleEvent(time::milliseconds(500),
                          bind(&FacesFixture2::checkPrefix, this, true));

  regPrefixId = face.registerPrefix("/Hello/World",
                                    bind(&FacesFixture3::onRegSucceeded, this),
                                    bind(&FacesFixture3::onRegFailed, this));

  scheduler.scheduleEvent(time::seconds(1),
    bind(&Face::unregisterPrefix, &face,
         regPrefixId,
         static_cast<UnregisterPrefixSuccessCallback>(bind(&FacesFixture3::onUnregSucceeded, this)),
         static_cast<UnregisterPrefixFailureCallback>(bind(&FacesFixture3::onUnregFailed, this))));

  scheduler.scheduleEvent(time::milliseconds(1500),
                          bind(&FacesFixture2::checkPrefix, this, false));

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nRegFailures, 0);
  BOOST_CHECK_EQUAL(nRegSuccesses, 1);

  BOOST_CHECK_EQUAL(nUnregFailures, 0);
  BOOST_CHECK_EQUAL(nUnregSuccesses, 1);
}

BOOST_AUTO_TEST_CASE(SetRegexFilterButNoRegister)
{
  Face face;
  Face face2(face.getIoService());
  Scheduler scheduler(face.getIoService());
  scheduler.scheduleEvent(time::seconds(2),
                          bind(&FacesFixture::terminate, this, ref(face)));

  face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
                         bind(&FacesFixture::onInterestRegex, this,
                              ref(face), _1, _2));

  // prefix is not registered, and also does not match regex
  scheduler.scheduleEvent(time::milliseconds(200),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a")));

  // matches regex, but prefix is not registered
  scheduler.scheduleEvent(time::milliseconds(300),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a/b")));

  // matches regex, but prefix is not registered
  scheduler.scheduleEvent(time::milliseconds(400),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a/b/c")));

  // prefix is not registered, and also does not match regex
  scheduler.scheduleEvent(time::milliseconds(500),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a/b/d")));

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nRegFailures, 0);
  BOOST_CHECK_EQUAL(nInInterests, 0);
  BOOST_CHECK_EQUAL(nTimeouts, 4);
  BOOST_CHECK_EQUAL(nData, 0);
}


BOOST_FIXTURE_TEST_CASE(SetRegexFilterAndRegister, FacesFixture3)
{
  Face face;
  Face face2(face.getIoService());
  Scheduler scheduler(face.getIoService());
  scheduler.scheduleEvent(time::seconds(2),
                          bind(&FacesFixture::terminate, this, ref(face)));

  face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
                         bind(&FacesFixture::onInterestRegex, this,
                              ref(face), _1, _2));

  face.registerPrefix("/Hello/World",
                      bind(&FacesFixture3::onRegSucceeded, this),
                      bind(&FacesFixture3::onRegFailed, this));

  scheduler.scheduleEvent(time::milliseconds(200),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a"))); // shouldn't match

  scheduler.scheduleEvent(time::milliseconds(300),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a/b"))); // should match

  scheduler.scheduleEvent(time::milliseconds(400),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a/b/c"))); // should match

  scheduler.scheduleEvent(time::milliseconds(500),
                          bind(&FacesFixture::expressInterest, this,
                               ref(face2), Name("/Hello/World/a/b/d"))); // should not match

  BOOST_REQUIRE_NO_THROW(face.processEvents());

  BOOST_CHECK_EQUAL(nRegFailures, 0);
  BOOST_CHECK_EQUAL(nRegSuccesses, 1);

  BOOST_CHECK_EQUAL(nInInterests, 2);
  BOOST_CHECK_EQUAL(nTimeouts, 4);
}

BOOST_AUTO_TEST_SUITE_END()

} // tests
} // namespace ndn
