/******************************************************************************
 *
 *  Copyright (C) 2014 Google, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#define LOG_TAG "bt_osi_reactor"

#include "osi/include/reactor.h"

#include <base/logging.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <unistd.h>

#include <mutex>

#include "osi/include/allocator.h"
#include "osi/include/list.h"
#include "osi/include/log.h"

#if !defined(EFD_SEMAPHORE)
#define EFD_SEMAPHORE (1 << 0)
#endif

struct reactor_t {
  int epoll_fd;
  int event_fd;
  std::mutex* list_mutex;
  list_t* invalidation_list;  // reactor objects that have been unregistered.
  pthread_t run_thread;       // the pthread on which reactor_run is executing.
  bool is_running;            // indicates whether |run_thread| is valid.
  bool object_removed;
};

struct reactor_object_t {
  int fd;              // the file descriptor to monitor for events.
  void* context;       // a context that's passed back to the *_ready functions.
  reactor_t* reactor;  // the reactor instance this object is registered with.
  std::mutex* mutex;  // protects the lifetime of this object and all variables.

  void (*read_ready)(void* context);   // function to call when the file
                                       // descriptor becomes readable.
  void (*write_ready)(void* context);  // function to call when the file
                                       // descriptor becomes writeable.
};

static reactor_status_t run_reactor(reactor_t* reactor, int iterations);

static const size_t MAX_EVENTS = 64;
static const eventfd_t EVENT_REACTOR_STOP = 1;

reactor_t* reactor_new(void) {
  reactor_t* ret = (reactor_t*)osi_calloc(sizeof(reactor_t));

  ret->epoll_fd = INVALID_FD;
  ret->event_fd = INVALID_FD;

  ret->epoll_fd = epoll_create(MAX_EVENTS);
  if (ret->epoll_fd == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s unable to create epoll instance: %s", __func__,
              strerror(errno));
    goto error;
  }

  ret->event_fd = eventfd(0, 0);
  if (ret->event_fd == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s unable to create eventfd: %s", __func__,
              strerror(errno));
    goto error;
  }

  ret->list_mutex = new std::mutex;
  ret->invalidation_list = list_new(NULL);
  if (!ret->invalidation_list) {
    LOG_ERROR(LOG_TAG, "%s unable to allocate object invalidation list.",
              __func__);
    goto error;
  }

  struct epoll_event event;
  memset(&event, 0, sizeof(event));
  event.events = EPOLLIN;
  event.data.ptr = NULL;
  if (epoll_ctl(ret->epoll_fd, EPOLL_CTL_ADD, ret->event_fd, &event) == -1) {
    LOG_ERROR(LOG_TAG, "%s unable to register eventfd with epoll set: %s",
              __func__, strerror(errno));
    goto error;
  }

  return ret;

error:;
  reactor_free(ret);
  return NULL;
}

void reactor_free(reactor_t* reactor) {
  if (!reactor) return;

  list_free(reactor->invalidation_list);
  close(reactor->event_fd);
  close(reactor->epoll_fd);
  osi_free(reactor);
}

reactor_status_t reactor_start(reactor_t* reactor) {
  CHECK(reactor != NULL);
  return run_reactor(reactor, 0);
}

reactor_status_t reactor_run_once(reactor_t* reactor) {
  CHECK(reactor != NULL);
  return run_reactor(reactor, 1);
}

void reactor_stop(reactor_t* reactor) {
  CHECK(reactor != NULL);

  eventfd_write(reactor->event_fd, EVENT_REACTOR_STOP);
}

reactor_object_t* reactor_register(reactor_t* reactor, int fd, void* context,
                                   void (*read_ready)(void* context),
                                   void (*write_ready)(void* context)) {
  CHECK(reactor != NULL);
  CHECK(fd != INVALID_FD);

  reactor_object_t* object =
      (reactor_object_t*)osi_calloc(sizeof(reactor_object_t));

  object->reactor = reactor;
  object->fd = fd;
  object->context = context;
  object->read_ready = read_ready;
  object->write_ready = write_ready;
  object->mutex = new std::mutex;

  struct epoll_event event;
  memset(&event, 0, sizeof(event));
  if (read_ready) event.events |= (EPOLLIN | EPOLLRDHUP);
  if (write_ready) event.events |= EPOLLOUT;
  event.data.ptr = object;

  if (epoll_ctl(reactor->epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1) {
    LOG_ERROR(LOG_TAG, "%s unable to register fd %d to epoll set: %s", __func__,
              fd, strerror(errno));
    delete object->mutex;
    osi_free(object);
    return NULL;
  }

  return object;
}

bool reactor_change_registration(reactor_object_t* object,
                                 void (*read_ready)(void* context),
                                 void (*write_ready)(void* context)) {
  CHECK(object != NULL);

  struct epoll_event event;
  memset(&event, 0, sizeof(event));
  if (read_ready) event.events |= (EPOLLIN | EPOLLRDHUP);
  if (write_ready) event.events |= EPOLLOUT;
  event.data.ptr = object;

  if (epoll_ctl(object->reactor->epoll_fd, EPOLL_CTL_MOD, object->fd, &event) ==
      -1) {
    LOG_ERROR(LOG_TAG, "%s unable to modify interest set for fd %d: %s",
              __func__, object->fd, strerror(errno));
    return false;
  }

  std::lock_guard<std::mutex> lock(*object->mutex);
  object->read_ready = read_ready;
  object->write_ready = write_ready;

  return true;
}

void reactor_unregister(reactor_object_t* obj) {
  CHECK(obj != NULL);

  reactor_t* reactor = obj->reactor;

  if (epoll_ctl(reactor->epoll_fd, EPOLL_CTL_DEL, obj->fd, NULL) == -1)
    LOG_ERROR(LOG_TAG, "%s unable to unregister fd %d from epoll set: %s",
              __func__, obj->fd, strerror(errno));

  if (reactor->is_running &&
      pthread_equal(pthread_self(), reactor->run_thread)) {
    reactor->object_removed = true;
    return;
  }

  {
    std::unique_lock<std::mutex> lock(*reactor->list_mutex);
    list_append(reactor->invalidation_list, obj);
  }

  // Taking the object lock here makes sure a callback for |obj| isn't
  // currently executing. The reactor thread must then either be before
  // the callbacks or after. If after, we know that the object won't be
  // referenced because it has been taken out of the epoll set. If before,
  // it won't be referenced because the reactor thread will check the
  // invalidation_list and find it in there. So by taking this lock, we
  // are waiting until the reactor thread drops all references to |obj|.
  // One the wait completes, we can unlock and destroy |obj| safely.
  obj->mutex->lock();
  obj->mutex->unlock();
  delete obj->mutex;
  osi_free(obj);
}

// Runs the reactor loop for a maximum of |iterations|.
// 0 |iterations| means loop forever.
// |reactor| may not be NULL.
static reactor_status_t run_reactor(reactor_t* reactor, int iterations) {
  CHECK(reactor != NULL);

  reactor->run_thread = pthread_self();
  reactor->is_running = true;

  struct epoll_event events[MAX_EVENTS];
  for (int i = 0; iterations == 0 || i < iterations; ++i) {
    {
      std::lock_guard<std::mutex> lock(*reactor->list_mutex);
      list_clear(reactor->invalidation_list);
    }

    int ret;
    OSI_NO_INTR(ret = epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, -1));
    if (ret == -1) {
      LOG_ERROR(LOG_TAG, "%s error in epoll_wait: %s", __func__,
                strerror(errno));
      reactor->is_running = false;
      return REACTOR_STATUS_ERROR;
    }

    for (int j = 0; j < ret; ++j) {
      // The event file descriptor is the only one that registers with
      // a NULL data pointer. We use the NULL to identify it and break
      // out of the reactor loop.
      if (events[j].data.ptr == NULL) {
        eventfd_t value;
        eventfd_read(reactor->event_fd, &value);
        reactor->is_running = false;
        return REACTOR_STATUS_STOP;
      }

      reactor_object_t* object = (reactor_object_t*)events[j].data.ptr;

      std::unique_lock<std::mutex> lock(*reactor->list_mutex);
      if (list_contains(reactor->invalidation_list, object)) {
        continue;
      }

      // Downgrade the list lock to an object lock.
      {
        std::lock_guard<std::mutex> obj_lock(*object->mutex);
        lock.unlock();

        reactor->object_removed = false;
        if (events[j].events & (EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR) &&
            object->read_ready)
          object->read_ready(object->context);
        if (!reactor->object_removed && events[j].events & EPOLLOUT &&
            object->write_ready)
          object->write_ready(object->context);
      }

      if (reactor->object_removed) {
        delete object->mutex;
        osi_free(object);
      }
    }
  }

  reactor->is_running = false;
  return REACTOR_STATUS_DONE;
}
