/* -*- 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 "boost-test.hpp"

namespace ndn {


class FacesFixture
{
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));

  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()

} // namespace ndn
