/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2018,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD 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.
 *
 * NFD 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
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "rib-io-fixture.hpp"
#include "core/extended-error-message.hpp"
#include <iostream>

namespace nfd {
namespace tests {

RibIoFixture::RibIoFixture()
{
  std::mutex m;
  std::condition_variable cv;

  g_ribThread = boost::thread([&] {
    {
      std::lock_guard<std::mutex> lock(m);
      g_ribIo = &getGlobalIoService();
      setRibIoService(g_ribIo);
      BOOST_ASSERT(&g_io != g_ribIo);
      BOOST_ASSERT(g_ribIo == &getRibIoService());
    }
    cv.notify_all();

    try {
      while (true) {
        {
          std::unique_lock<std::mutex> lock(m_ribPollMutex);
          m_ribPollStartCv.wait(lock, [this] { return m_shouldStopRibIo || m_shouldPollRibIo; });
          if (m_shouldStopRibIo) {
            break;
          }
          BOOST_ASSERT(m_shouldPollRibIo);
        }

        if (g_ribIo->stopped()) {
          g_ribIo->reset();
        }
        while (g_ribIo->poll() > 0)
          ;

        {
          std::lock_guard<std::mutex> lock(m_ribPollMutex);
          m_shouldPollRibIo = false;
        }
        m_ribPollEndCv.notify_all();
      }
    }
    catch (const std::exception& e) {
      std::cerr << "Exception in RIB thread: " << getExtendedErrorMessage(e) << std::endl;
      throw;
    }
  });

  {
    std::unique_lock<std::mutex> lock(m);
    cv.wait(lock, [this] { return g_ribIo != nullptr; });
  }
}

RibIoFixture::~RibIoFixture()
{
  {
    std::lock_guard<std::mutex> lock(m_ribPollMutex);
    m_shouldStopRibIo = true;
  }
  m_ribPollStartCv.notify_all();
  g_ribThread.join();
}

void
RibIoFixture::poll()
{
  BOOST_ASSERT(&getGlobalIoService() == &g_io);

  size_t nHandlersRun = 0;
  do {
    {
      std::lock_guard<std::mutex> lock(m_ribPollMutex);
      m_shouldPollRibIo = true;
    }
    m_ribPollStartCv.notify_all();

    if (g_io.stopped()) {
      g_io.reset();
    }

    nHandlersRun = g_io.poll();

    {
      std::unique_lock<std::mutex> lock(m_ribPollMutex);
      m_ribPollEndCv.wait(lock, [this] { return !m_shouldPollRibIo; });
    }
  } while (nHandlersRun > 0);
}

void
RibIoTimeFixture::advanceClocks(time::nanoseconds tick, time::nanoseconds total)
{
  BOOST_ASSERT(tick > time::nanoseconds::zero());
  BOOST_ASSERT(total >= time::nanoseconds::zero());

  time::nanoseconds remaining = total;
  while (remaining > time::nanoseconds::zero()) {
    if (remaining >= tick) {
      steadyClock->advance(tick);
      systemClock->advance(tick);
      remaining -= tick;
    }
    else {
      steadyClock->advance(remaining);
      systemClock->advance(remaining);
      remaining = time::nanoseconds::zero();
    }

    poll();
  }
}

} // namespace tests
} // namespace nfd
