// Copyright (c) 2011, 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_VM_MESSAGE_H_
#define RUNTIME_VM_MESSAGE_H_

#include <memory>
#include <utility>

#include "platform/assert.h"
#include "vm/allocation.h"
#include "vm/finalizable_data.h"
#include "vm/globals.h"
#include "vm/tagged_pointer.h"

// Duplicated from dart_api.h to avoid including the whole header.
typedef int64_t Dart_Port;

namespace dart {

class PersistentHandle;

class Message {
 public:
  typedef enum {
    kNormalPriority = 0,  // Deliver message when idle.
    kOOBPriority = 1,     // Deliver message asap.

    // Iteration.
    kFirstPriority = 0,
    kNumPriorities = 2,
  } Priority;

  // Values defining the type of OOB messages. OOB messages can only be
  // fixed length arrays where the first element is a Smi with one of the
  // valid values below.
  typedef enum {
    kIllegalOOB = 0,
    kServiceOOBMsg = 1,
    kIsolateLibOOBMsg = 2,
    kDelayedIsolateLibOOBMsg = 3,
  } OOBMsgTag;

  // A port number which is never used.
  static const Dart_Port kIllegalPort;

  // A new message to be sent between two isolates. The data handed to this
  // message will be disposed by calling free() once the message object is
  // being destructed (after delivery or when the receiving port is closed).
  Message(Dart_Port dest_port,
          uint8_t* snapshot,
          intptr_t snapshot_length,
          MessageFinalizableData* finalizable_data,
          Priority priority);

  // Message objects can also carry raw ObjectPtr for Smis and objects in
  // the VM heap. This is indicated by setting the len_ field to 0.
  Message(Dart_Port dest_port, ObjectPtr raw_obj, Priority priority);

  // A message sent from SendPort.send or Isolate.exit where sender and
  // receiver are in the same isolate group.
  Message(Dart_Port dest_port, PersistentHandle* handle, Priority priority);

  // A message sent from GC to run a finalizer.
  Message(PersistentHandle* handle, Priority priority);

  ~Message();

  template <typename... Args>
  static std::unique_ptr<Message> New(Args&&... args) {
    return std::unique_ptr<Message>(new Message(std::forward<Args>(args)...));
  }

  Dart_Port dest_port() const { return dest_port_; }

  uint8_t* snapshot() const {
    ASSERT(IsSnapshot());
    return payload_.snapshot_;
  }
  intptr_t snapshot_length() const { return snapshot_length_; }

  MessageFinalizableData* finalizable_data() { return finalizable_data_; }

  intptr_t Size() const {
    intptr_t size = snapshot_length_;
    if (finalizable_data_ != nullptr) {
      size += finalizable_data_->external_size();
    }
    return size;
  }

  ObjectPtr raw_obj() const {
    ASSERT(IsRaw());
    return payload_.raw_obj_;
  }
  PersistentHandle* persistent_handle() const {
    ASSERT(IsPersistentHandle() || IsFinalizerInvocationRequest());
    return payload_.persistent_handle_;
  }
  Priority priority() const { return priority_; }

  // A message processed at any interrupt point (stack overflow check) instead
  // of at the top of the message loop. Control messages from dart:isolate or
  // vm-service requests.
  bool IsOOB() const { return priority_ == Message::kOOBPriority; }
  bool IsSnapshot() const {
    return !IsRaw() && !IsPersistentHandle() && !IsFinalizerInvocationRequest();
  }
  // A message whose object is an immortal object from the vm-isolate's heap.
  bool IsRaw() const { return snapshot_length_ == 0; }
  // A message sent from SendPort.send or Isolate.exit where sender and
  // receiver are in the same isolate group.
  bool IsPersistentHandle() const {
    return snapshot_length_ == kPersistentHandleSnapshotLen;
  }
  // A message sent from GC to run a finalizer.
  bool IsFinalizerInvocationRequest() const {
    return snapshot_length_ == kFinalizerSnapshotLen;
  }

  void DropFinalizers() {
    if (finalizable_data_ != nullptr) {
      finalizable_data_->DropFinalizers();
    }
  }

 private:
  static intptr_t const kPersistentHandleSnapshotLen = -1;
  static intptr_t const kFinalizerSnapshotLen = -2;

  friend class MessageQueue;

  Message* next_ = nullptr;
  Dart_Port dest_port_;
  union Payload {
    Payload(uint8_t* snapshot) : snapshot_(snapshot) {}
    Payload(ObjectPtr raw_obj) : raw_obj_(raw_obj) {}
    Payload(PersistentHandle* persistent_handle)
        : persistent_handle_(persistent_handle) {}

    uint8_t* snapshot_;
    ObjectPtr raw_obj_;
    PersistentHandle* persistent_handle_;
  } payload_;
  intptr_t snapshot_length_ = 0;
  MessageFinalizableData* finalizable_data_ = nullptr;
  Priority priority_;

  DISALLOW_COPY_AND_ASSIGN(Message);
};

// There is a message queue per isolate.
class MessageQueue {
 public:
  MessageQueue();
  ~MessageQueue();

  void Enqueue(std::unique_ptr<Message> msg, bool before_events);

  // Gets the next message from the message queue or nullptr if no
  // message is available.  This function will not block.
  std::unique_ptr<Message> Dequeue();

  bool IsEmpty() { return head_ == nullptr; }

  // Clear all messages from the message queue.
  void Clear();

  // Iterator class.
  class Iterator : public ValueObject {
   public:
    explicit Iterator(const MessageQueue* queue);
    virtual ~Iterator();

    void Reset(const MessageQueue* queue);

    // Returns false when there are no more messages left.
    bool HasNext();

    // Returns the current message and moves forward.
    Message* Next();

   private:
    Message* next_;
  };

  intptr_t Length() const;

 private:
  Message* head_;
  Message* tail_;

  DISALLOW_COPY_AND_ASSIGN(MessageQueue);
};

}  // namespace dart

#endif  // RUNTIME_VM_MESSAGE_H_
