// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_BIN_EVENTHANDLER_H_
#define RUNTIME_BIN_EVENTHANDLER_H_

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/isolate_data.h"

#include "platform/hashmap.h"
#include "platform/priority_queue.h"

namespace dart {
namespace bin {

// Flags used to provide information and actions to the eventhandler
// when sending a message about a file descriptor. These flags should
// be kept in sync with the constants in socket_patch.dart. For more
// information see the comments in socket_patch.dart
enum MessageFlags {
  kInEvent = 0,
  kOutEvent = 1,
  kErrorEvent = 2,
  kCloseEvent = 3,
  kDestroyedEvent = 4,
  kCloseCommand = 8,
  kShutdownReadCommand = 9,
  kShutdownWriteCommand = 10,
  kReturnTokenCommand = 11,
  kSetEventMaskCommand = 12,
  kListeningSocket = 16,
  kPipe = 17,
};

// clang-format off
#define COMMAND_MASK ((1 << kCloseCommand) |                                   \
                      (1 << kShutdownReadCommand) |                            \
                      (1 << kShutdownWriteCommand) |                           \
                      (1 << kReturnTokenCommand) |                             \
                      (1 << kSetEventMaskCommand))
#define EVENT_MASK ((1 << kInEvent) |                                          \
                    (1 << kOutEvent) |                                         \
                    (1 << kErrorEvent) |                                       \
                    (1 << kCloseEvent) |                                       \
                    (1 << kDestroyedEvent))
#define IS_COMMAND(data, command_bit)                                          \
    ((data & COMMAND_MASK) == (1 << command_bit))  // NOLINT
#define IS_EVENT(data, event_bit)                                              \
    ((data & EVENT_MASK) == (1 << event_bit))  // NOLINT
#define IS_IO_EVENT(data)                                                      \
    ((data & (1 << kInEvent | 1 << kOutEvent | 1 << kCloseEvent)) != 0 &&      \
     (data & ~(1 << kInEvent | 1 << kOutEvent | 1 << kCloseEvent)) == 0)
#define IS_LISTENING_SOCKET(data)                                              \
    ((data & (1 << kListeningSocket)) != 0)  // NOLINT
#define TOKEN_COUNT(data) (data & ((1 << kCloseCommand) - 1))
// clang-format on

class TimeoutQueue {
 public:
  TimeoutQueue() {}

  ~TimeoutQueue() {
    while (HasTimeout())
      RemoveCurrent();
  }

  bool HasTimeout() const { return !timeouts_.IsEmpty(); }

  int64_t CurrentTimeout() const {
    ASSERT(!timeouts_.IsEmpty());
    return timeouts_.Minimum().priority;
  }

  Dart_Port CurrentPort() const {
    ASSERT(!timeouts_.IsEmpty());
    return timeouts_.Minimum().value;
  }

  void RemoveCurrent() { timeouts_.RemoveMinimum(); }

  void UpdateTimeout(Dart_Port port, int64_t timeout) {
    if (timeout < 0) {
      timeouts_.RemoveByValue(port);
    } else {
      timeouts_.InsertOrChangePriority(timeout, port);
    }
  }

 private:
  PriorityQueue<int64_t, Dart_Port> timeouts_;
  int64_t next_timeout_;

  DISALLOW_COPY_AND_ASSIGN(TimeoutQueue);
};

class InterruptMessage {
 public:
  intptr_t id;
  Dart_Port dart_port;
  int64_t data;
};

static const int kInterruptMessageSize = sizeof(InterruptMessage);
static const int kInfinityTimeout = -1;
static const int kTimerId = -1;
static const int kShutdownId = -2;

template <typename T>
class CircularLinkedList {
 public:
  CircularLinkedList() : head_(NULL) {}

  typedef void (*ClearFun)(void* value);

  // Returns true if the list was empty.
  bool Add(T t) {
    Entry* e = new Entry(t);
    if (head_ == NULL) {
      // Empty list, make e head, and point to itself.
      e->next_ = e;
      e->prev_ = e;
      head_ = e;
      return true;
    } else {
      // Insert e as the last element in the list.
      e->prev_ = head_->prev_;
      e->next_ = head_;
      e->prev_->next_ = e;
      head_->prev_ = e;
      return false;
    }
  }

  void RemoveHead(ClearFun clear = NULL) {
    ASSERT(head_ != NULL);

    Entry* e = head_;
    if (e->next_ == e) {
      head_ = NULL;
    } else {
      e->prev_->next_ = e->next_;
      e->next_->prev_ = e->prev_;
      head_ = e->next_;
    }
    if (clear != NULL) {
      clear(reinterpret_cast<void*>(e->t));
    }
    delete e;
  }

  void Remove(T item) {
    if (head_ == NULL) {
      return;
    } else if (head_ == head_->next_) {
      if (head_->t == item) {
        delete head_;
        head_ = NULL;
        return;
      }
    } else {
      Entry* current = head_;
      do {
        if (current->t == item) {
          Entry* next = current->next_;
          Entry* prev = current->prev_;
          prev->next_ = next;
          next->prev_ = prev;

          if (current == head_) {
            head_ = head_->next_;
          }

          delete current;
          return;
        }
        current = current->next_;
      } while (current != head_);
    }
  }

  void RemoveAll(ClearFun clear = NULL) {
    while (HasHead()) {
      RemoveHead(clear);
    }
  }

  T head() const { return head_->t; }

  bool HasHead() const { return head_ != NULL; }

  void Rotate() {
    if (head_ != NULL) {
      ASSERT(head_->next_ != NULL);
      head_ = head_->next_;
    }
  }

 private:
  struct Entry {
    explicit Entry(const T& t) : t(t), next_(NULL), prev_(NULL) {}
    const T t;
    Entry* next_;
    Entry* prev_;
  };

  Entry* head_;

  DISALLOW_COPY_AND_ASSIGN(CircularLinkedList);
};

class DescriptorInfoBase {
 public:
  explicit DescriptorInfoBase(intptr_t fd) : fd_(fd) { ASSERT(fd_ != -1); }

  virtual ~DescriptorInfoBase() {}

  // The OS descriptor.
  intptr_t fd() { return fd_; }

  // Whether this descriptor refers to an underlying listening OS socket.
  virtual bool IsListeningSocket() const = 0;

  // Inserts or updates a new Dart_Port which is interested in events specified
  // in `mask`.
  virtual void SetPortAndMask(Dart_Port port, intptr_t mask) = 0;

  // Removes a port from the interested listeners.
  virtual void RemovePort(Dart_Port port) = 0;

  // Removes all ports from the interested listeners.
  virtual void RemoveAllPorts() = 0;

  // Returns a port to which `events_ready` can be sent to. It will also
  // decrease the token count by 1 for this port.
  virtual Dart_Port NextNotifyDartPort(intptr_t events_ready) = 0;

  // Will post `data` to all known Dart_Ports. It will also decrease the token
  // count by 1 for all ports.
  virtual void NotifyAllDartPorts(uintptr_t events) = 0;

  // Returns `count` tokens for the given port.
  virtual void ReturnTokens(Dart_Port port, int count) = 0;

  // Returns the union of event masks of all ports. If a port has a non-positive
  // token count it's mask is assumed to be 0.
  virtual intptr_t Mask() = 0;

  // Closes this descriptor.
  virtual void Close() = 0;

 protected:
  intptr_t fd_;

 private:
  DISALLOW_COPY_AND_ASSIGN(DescriptorInfoBase);
};

// Describes a OS descriptor (e.g. file descriptor on linux or HANDLE on
// windows) which is connected to a single Dart_Port.
//
// Subclasses of this class can be e.g. connected tcp sockets.
template <typename DI>
class DescriptorInfoSingleMixin : public DI {
 private:
  static const int kTokenCount = 16;

 public:
  DescriptorInfoSingleMixin(intptr_t fd, bool disable_tokens)
      : DI(fd),
        port_(0),
        tokens_(kTokenCount),
        mask_(0),
        disable_tokens_(disable_tokens) {}

  virtual ~DescriptorInfoSingleMixin() {}

  virtual bool IsListeningSocket() const { return false; }

  virtual void SetPortAndMask(Dart_Port port, intptr_t mask) {
    ASSERT(port_ == 0 || port == port_);
    port_ = port;
    mask_ = mask;
  }

  virtual void RemovePort(Dart_Port port) {
    // TODO(dart:io): Find out where we call RemovePort() with the invalid
    // port. Afterwards remove the part in the ASSERT here.
    ASSERT(port_ == 0 || port_ == port);
    port_ = 0;
    mask_ = 0;
  }

  virtual void RemoveAllPorts() {
    port_ = 0;
    mask_ = 0;
  }

  virtual Dart_Port NextNotifyDartPort(intptr_t events_ready) {
    ASSERT(IS_IO_EVENT(events_ready) ||
           IS_EVENT(events_ready, kDestroyedEvent));
    if (!disable_tokens_) {
      tokens_--;
    }
    return port_;
  }

  virtual void NotifyAllDartPorts(uintptr_t events) {
    // Unexpected close, asynchronous destroy or error events are the only
    // ones we broadcast to all listeners.
    ASSERT(IS_EVENT(events, kCloseEvent) || IS_EVENT(events, kErrorEvent) ||
           IS_EVENT(events, kDestroyedEvent));

    if (port_ != 0) {
      DartUtils::PostInt32(port_, events);
    }
    if (!disable_tokens_) {
      tokens_--;
    }
  }

  virtual void ReturnTokens(Dart_Port port, int count) {
    ASSERT(port_ == port);
    if (!disable_tokens_) {
      tokens_ += count;
    }
    ASSERT(tokens_ <= kTokenCount);
  }

  virtual intptr_t Mask() {
    if (tokens_ <= 0) {
      return 0;
    }
    return mask_;
  }

  virtual void Close() { DI::Close(); }

 private:
  Dart_Port port_;
  int tokens_;
  intptr_t mask_;
  bool disable_tokens_;

  DISALLOW_COPY_AND_ASSIGN(DescriptorInfoSingleMixin);
};

// Describes a OS descriptor (e.g. file descriptor on linux or HANDLE on
// windows) which is connected to multiple Dart_Port's.
//
// Subclasses of this class can be e.g. a listening socket which multiple
// isolates are listening on.
template <typename DI>
class DescriptorInfoMultipleMixin : public DI {
 private:
  static const int kTokenCount = 4;

  static bool SamePortValue(void* key1, void* key2) {
    return reinterpret_cast<Dart_Port>(key1) ==
           reinterpret_cast<Dart_Port>(key2);
  }

  static uint32_t GetHashmapHashFromPort(Dart_Port port) {
    return static_cast<uint32_t>(port & 0xFFFFFFFF);
  }

  static void* GetHashmapKeyFromPort(Dart_Port port) {
    return reinterpret_cast<void*>(port);
  }

  static bool IsReadingMask(intptr_t mask) {
    if (mask == (1 << kInEvent)) {
      return true;
    } else {
      ASSERT(mask == 0);
      return false;
    }
  }

  struct PortEntry {
    Dart_Port dart_port;
    intptr_t is_reading;
    intptr_t token_count;

    bool IsReady() { return token_count > 0 && is_reading != 0; }
  };

 public:
  DescriptorInfoMultipleMixin(intptr_t fd, bool disable_tokens)
      : DI(fd),
        tokens_map_(&SamePortValue, kTokenCount),
        disable_tokens_(disable_tokens) {}

  virtual ~DescriptorInfoMultipleMixin() { RemoveAllPorts(); }

  virtual bool IsListeningSocket() const { return true; }

  virtual void SetPortAndMask(Dart_Port port, intptr_t mask) {
    SimpleHashMap::Entry* entry = tokens_map_.Lookup(
        GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), true);
    PortEntry* pentry;
    if (entry->value == NULL) {
      pentry = new PortEntry();
      pentry->dart_port = port;
      pentry->token_count = kTokenCount;
      pentry->is_reading = IsReadingMask(mask);
      entry->value = reinterpret_cast<void*>(pentry);

      if (pentry->IsReady()) {
        active_readers_.Add(pentry);
      }
    } else {
      pentry = reinterpret_cast<PortEntry*>(entry->value);
      bool was_ready = pentry->IsReady();
      pentry->is_reading = IsReadingMask(mask);
      bool is_ready = pentry->IsReady();

      if (was_ready && !is_ready) {
        active_readers_.Remove(pentry);
      } else if (!was_ready && is_ready) {
        active_readers_.Add(pentry);
      }
    }

#ifdef DEBUG
    // To ensure that all readers are ready.
    int ready_count = 0;

    if (active_readers_.HasHead()) {
      PortEntry* root = reinterpret_cast<PortEntry*>(active_readers_.head());
      PortEntry* current = root;
      do {
        ASSERT(current->IsReady());
        ready_count++;
        active_readers_.Rotate();
        current = active_readers_.head();
      } while (current != root);
    }

    for (SimpleHashMap::Entry* entry = tokens_map_.Start(); entry != NULL;
         entry = tokens_map_.Next(entry)) {
      PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value);
      if (pentry->IsReady()) {
        ready_count--;
      }
    }
    // Ensure all ready items are in `active_readers_`.
    ASSERT(ready_count == 0);
#endif
  }

  virtual void RemovePort(Dart_Port port) {
    SimpleHashMap::Entry* entry = tokens_map_.Lookup(
        GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false);
    if (entry != NULL) {
      PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value);
      if (pentry->IsReady()) {
        active_readers_.Remove(pentry);
      }
      tokens_map_.Remove(GetHashmapKeyFromPort(port),
                         GetHashmapHashFromPort(port));
      delete pentry;
    } else {
      // NOTE: This is a listening socket which has been immediately closed.
      //
      // If a listening socket is not listened on, the event handler does not
      // know about it beforehand. So the first time the event handler knows
      // about it, is when it is supposed to be closed. We therefore do nothing
      // here.
      //
      // But whether to close it, depends on whether other isolates have it open
      // as well or not.
    }
  }

  virtual void RemoveAllPorts() {
    for (SimpleHashMap::Entry* entry = tokens_map_.Start(); entry != NULL;
         entry = tokens_map_.Next(entry)) {
      PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value);
      entry->value = NULL;
      active_readers_.Remove(pentry);
      delete pentry;
    }
    tokens_map_.Clear();
    active_readers_.RemoveAll(DeletePortEntry);
  }

  virtual Dart_Port NextNotifyDartPort(intptr_t events_ready) {
    // We're only sending `kInEvents` if there are multiple listeners (which is
    // listening socktes).
    ASSERT(IS_EVENT(events_ready, kInEvent) ||
           IS_EVENT(events_ready, kDestroyedEvent));

    if (active_readers_.HasHead()) {
      PortEntry* pentry = reinterpret_cast<PortEntry*>(active_readers_.head());

      // Update token count.
      if (!disable_tokens_) {
        pentry->token_count--;
      }
      if (pentry->token_count <= 0) {
        active_readers_.RemoveHead();
      } else {
        active_readers_.Rotate();
      }

      return pentry->dart_port;
    }
    return 0;
  }

  virtual void NotifyAllDartPorts(uintptr_t events) {
    // Unexpected close, asynchronous destroy or error events are the only
    // ones we broadcast to all listeners.
    ASSERT(IS_EVENT(events, kCloseEvent) || IS_EVENT(events, kErrorEvent) ||
           IS_EVENT(events, kDestroyedEvent));

    for (SimpleHashMap::Entry* entry = tokens_map_.Start(); entry != NULL;
         entry = tokens_map_.Next(entry)) {
      PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value);
      DartUtils::PostInt32(pentry->dart_port, events);

      // Update token count.
      bool was_ready = pentry->IsReady();
      if (!disable_tokens_) {
        pentry->token_count--;
      }

      if (was_ready && (pentry->token_count <= 0)) {
        active_readers_.Remove(pentry);
      }
    }
  }

  virtual void ReturnTokens(Dart_Port port, int count) {
    SimpleHashMap::Entry* entry = tokens_map_.Lookup(
        GetHashmapKeyFromPort(port), GetHashmapHashFromPort(port), false);
    ASSERT(entry != NULL);

    PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value);
    bool was_ready = pentry->IsReady();
    if (!disable_tokens_) {
      pentry->token_count += count;
    }
    ASSERT(pentry->token_count <= kTokenCount);
    bool is_ready = pentry->IsReady();
    if (!was_ready && is_ready) {
      active_readers_.Add(pentry);
    }
  }

  virtual intptr_t Mask() {
    if (active_readers_.HasHead()) {
      return 1 << kInEvent;
    }
    return 0;
  }

  virtual void Close() { DI::Close(); }

 private:
  static void DeletePortEntry(void* data) {
    PortEntry* entry = reinterpret_cast<PortEntry*>(data);
    delete entry;
  }

  // The [Dart_Port]s which are not paused (i.e. are interested in read events,
  // i.e. `mask == (1 << kInEvent)`) and we have enough tokens to communicate
  // with them.
  CircularLinkedList<PortEntry*> active_readers_;

  // A convenience mapping:
  //   Dart_Port -> struct PortEntry { dart_port, mask, token_count }
  SimpleHashMap tokens_map_;

  bool disable_tokens_;

  DISALLOW_COPY_AND_ASSIGN(DescriptorInfoMultipleMixin);
};

}  // namespace bin
}  // namespace dart

// The event handler delegation class is OS specific.
#if defined(HOST_OS_ANDROID)
#include "bin/eventhandler_android.h"
#elif defined(HOST_OS_FUCHSIA)
#include "bin/eventhandler_fuchsia.h"
#elif defined(HOST_OS_LINUX)
#include "bin/eventhandler_linux.h"
#elif defined(HOST_OS_MACOS)
#include "bin/eventhandler_macos.h"
#elif defined(HOST_OS_WINDOWS)
#include "bin/eventhandler_win.h"
#else
#error Unknown target os.
#endif

namespace dart {
namespace bin {

class EventHandler {
 public:
  EventHandler() {}
  void SendData(intptr_t id, Dart_Port dart_port, int64_t data) {
    delegate_.SendData(id, dart_port, data);
  }

  /**
   * Signal to main thread that event handler is done.
   */
  void NotifyShutdownDone();

  /**
   * Start the event-handler.
   */
  static void Start();

  /**
   * Stop the event-handler. It's expected that there will be no further calls
   * to SendData after a call to Stop.
   */
  static void Stop();

  static EventHandlerImplementation* delegate();

  static void SendFromNative(intptr_t id, Dart_Port port, int64_t data);

 private:
  friend class EventHandlerImplementation;
  EventHandlerImplementation delegate_;

  DISALLOW_COPY_AND_ASSIGN(EventHandler);
};

}  // namespace bin
}  // namespace dart

#endif  // RUNTIME_BIN_EVENTHANDLER_H_
