// Copyright 2015 The Weave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "examples/provider/event_task_runner.h"

#include <signal.h>

namespace weave {
namespace examples {

namespace {
event_base* g_event_base = nullptr;
}

void EventTaskRunner::PostDelayedTask(
    const tracked_objects::Location& from_here,
    const base::Closure& task,
    base::TimeDelta delay) {
  base::Time new_time = base::Time::Now() + delay;
  if (queue_.empty() || new_time < queue_.top().first.first) {
    ReScheduleEvent(delay);
  }
  queue_.emplace(std::make_pair(new_time, ++counter_), task);
}

void EventTaskRunner::AddIoCompletionTask(
    int fd,
    int16_t what,
    const EventTaskRunner::IoCompletionCallback& task) {
  int16_t flags = EV_PERSIST | EV_ET;
  flags |= (what & kReadable) ? EV_READ : 0;
  flags |= (what & kWriteable) ? EV_WRITE : 0;
  flags |= (what & kClosed) ? EV_CLOSED : 0;
  event* ioevent = event_new(base_.get(), fd, flags, FdEventHandler, this);
  EventPtr<event> ioeventPtr{ioevent};
  fd_task_map_.emplace(fd, std::make_pair(std::move(ioeventPtr), task));
  event_add(ioevent, nullptr);
}

void EventTaskRunner::RemoveIoCompletionTask(int fd) {
  fd_task_map_.erase(fd);
}

void EventTaskRunner::Run() {
  g_event_base = base_.get();

  struct sigaction sa = {};
  sa.sa_handler = [](int signal) {
    event_base_loopexit(g_event_base, nullptr);
  };
  sigfillset(&sa.sa_mask);
  sigaction(SIGINT, &sa, nullptr);

  event_base_loop(g_event_base, EVLOOP_NO_EXIT_ON_EMPTY);
  g_event_base = nullptr;
}

void EventTaskRunner::ReScheduleEvent(base::TimeDelta delay) {
  timespec ts = delay.ToTimeSpec();
  timeval tv = {ts.tv_sec, ts.tv_nsec / 1000};
  event_add(task_event_.get(), &tv);
}

void EventTaskRunner::EventHandler(int /* fd */,
                                   int16_t /* what */,
                                   void* runner) {
  static_cast<EventTaskRunner*>(runner)->Process();
}

void EventTaskRunner::FreeEvent(event* evnt) {
  event_del(evnt);
  event_free(evnt);
}

void EventTaskRunner::Process() {
  while (!queue_.empty() && queue_.top().first.first <= base::Time::Now()) {
    auto cb = queue_.top().second;
    queue_.pop();
    cb.Run();
  }
  if (!queue_.empty()) {
    base::TimeDelta delta = std::max(
        base::TimeDelta(), queue_.top().first.first - base::Time::Now());
    ReScheduleEvent(delta);
  }
}

void EventTaskRunner::FdEventHandler(int fd, int16_t what, void* runner) {
  static_cast<EventTaskRunner*>(runner)->ProcessFd(fd, what);
}

void EventTaskRunner::ProcessFd(int fd, int16_t what) {
  auto it = fd_task_map_.find(fd);
  if (it != fd_task_map_.end()) {
    const IoCompletionCallback& callback = it->second.second;
    callback.Run(fd, what, this);
  }
}

}  // namespace examples
}  // namespace weave
