// 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 BIN_DBG_MESSAGE_H_
#define BIN_DBG_MESSAGE_H_

#include "bin/builtin.h"
#include "bin/utils.h"

#include "include/dart_debugger_api.h"

#include "platform/globals.h"
#include "platform/json.h"
#include "platform/thread.h"


namespace dart {
namespace bin {

// TODO(hausner): Need better error handling.
#define ASSERT_NOT_ERROR(handle)          \
  ASSERT(!Dart_IsError(handle))

#define RETURN_IF_ERROR(handle)           \
  if (Dart_IsError(handle)) {             \
    return Dart_GetError(handle);         \
  }


// Class to parse a JSON debug command message.
class MessageParser {
 public:
  MessageParser(const char* buf, int buf_length)
      : buf_(buf), buf_length_(buf_length) {
  }
  ~MessageParser() { }

  // Accessors.
  const char* buf() const { return buf_; }

  bool IsValidMessage() const;
  int MessageId() const;

  const char* Params() const;
  bool HasParam(const char* name) const;
  intptr_t GetIntParam(const char* name) const;
  intptr_t GetOptIntParam(const char* name, intptr_t default_val) const;

  // GetStringParam mallocs the buffer that it returns. Caller must free.
  char* GetStringParam(const char* name) const;

 private:
  const char* buf_;
  int buf_length_;

  DISALLOW_COPY_AND_ASSIGN(MessageParser);
};


// Class which represents a debug command message and handles it.
class DbgMessage {
 public:
  DbgMessage(int32_t cmd_idx, const char* start,
             const char* end, int debug_fd)
      : next_(NULL), cmd_idx_(cmd_idx),
        buffer_(NULL), buffer_len_(end - start),
        debug_fd_(debug_fd) {
    buffer_ = reinterpret_cast<char*>(malloc(buffer_len_));
    ASSERT(buffer_ != NULL);
    memmove(buffer_, start, buffer_len_);
  }
  ~DbgMessage() {
    next_ = NULL;
    free(buffer_);
  }

  // Accessors.
  DbgMessage* next() const { return next_; }
  void set_next(DbgMessage* next) { next_ = next; }
  char* buffer() const { return buffer_; }
  int32_t buffer_len() const { return buffer_len_; }
  int debug_fd() const { return debug_fd_; }

  // Handle debugger command message.
  // Returns true if the execution needs to resume after this message is
  // handled, false otherwise.
  bool HandleMessage();

  // Send reply after successful handling of command.
  void SendReply(dart::TextBuffer* msg);

  // Reply error returned by the command handler.
  void SendErrorReply(int msg_id, const char* err_msg);

  // Handlers for specific commands, they are static because these
  // functions are populated as function pointers into a dispatch table.
  static bool HandleResumeCmd(DbgMessage* msg);
  static bool HandleStepIntoCmd(DbgMessage* msg);
  static bool HandleStepOverCmd(DbgMessage* msg);
  static bool HandleStepOutCmd(DbgMessage* msg);
  static bool HandleGetLibrariesCmd(DbgMessage* msg);
  static bool HandleGetClassPropsCmd(DbgMessage* msg);
  static bool HandleGetLibPropsCmd(DbgMessage* msg);
  static bool HandleSetLibPropsCmd(DbgMessage* msg);
  static bool HandleGetGlobalsCmd(DbgMessage* msg);
  static bool HandleEvaluateExprCmd(DbgMessage* msg);
  static bool HandleGetObjPropsCmd(DbgMessage* msg);
  static bool HandleGetListCmd(DbgMessage* msg);
  static bool HandleGetScriptURLsCmd(DbgMessage* msg);
  static bool HandleGetSourceCmd(DbgMessage* msg);
  static bool HandleGetLineNumbersCmd(DbgMessage* msg);
  static bool HandleGetStackTraceCmd(DbgMessage* msg);
  static bool HandlePauseOnExcCmd(DbgMessage* msg);
  static bool HandleSetBpCmd(DbgMessage* msg);
  static bool HandleRemBpCmd(DbgMessage* msg);

 private:
  DbgMessage* next_;  // Next message in the queue.
  int32_t cmd_idx_;  // Isolate specific debugger command index.
  char* buffer_;  // Debugger command message.
  int32_t buffer_len_;  // Length of the debugger command message.
  int debug_fd_;  // Debugger connection on which replies are to be sent.

  DISALLOW_IMPLICIT_CONSTRUCTORS(DbgMessage);
};


// Class which represents a queue of debug command messages sent to an isolate.
class DbgMsgQueue {
 public:
  DbgMsgQueue(Dart_IsolateId isolate_id, DbgMsgQueue* next)
      : is_running_(true),
        is_interrupted_(false),
        msglist_head_(NULL),
        msglist_tail_(NULL),
        queued_output_messages_(64),
        isolate_id_(isolate_id),
        next_(next) {
  }
  ~DbgMsgQueue() {
    DbgMessage* msg = msglist_head_;
    while (msglist_head_ != NULL) {
      msglist_head_ = msglist_head_->next();
      delete msg;
      msg = msglist_head_;
    }
    msglist_tail_ = NULL;
    isolate_id_ = ILLEGAL_ISOLATE_ID;
    next_ = NULL;
  }

  // Accessors.
  Dart_IsolateId isolate_id() const { return isolate_id_; }
  DbgMsgQueue* next() const { return next_; }
  void set_next(DbgMsgQueue* next) { next_ = next; }

  // Add specified debug command message to the queue.
  void AddMessage(int32_t cmd_idx,
                  const char* start,
                  const char* end,
                  int debug_fd);

  // Notify an isolate of a pending vmservice message.
  void Notify();

  // Run a message loop which handles messages as they arrive until
  // normal program execution resumes.
  void MessageLoop();

  // Handle any pending debug command messages in the queue.  Return
  // value indicates whether a resume has been requested.
  bool HandlePendingMessages();

  // Interrupt Isolate.
  void InterruptIsolate();

  // Queue output messages, these are sent out when we hit an event.
  void QueueOutputMsg(dart::TextBuffer* msg);

  // Send all queued messages over to the debugger.
  void SendQueuedMsgs();

  // Send breakpoint event message over to the debugger.
  void SendBreakpointEvent(intptr_t bp_id, const Dart_CodeLocation& location);

  // Send Exception event message over to the debugger.
  void SendExceptionEvent(Dart_Handle exception, Dart_StackTrace trace);

  // Send Isolate event message over to the debugger.
  void SendIsolateEvent(Dart_IsolateId isolate_id, Dart_IsolateEvent kind);

 private:
  bool is_running_;  // True if isolate is running and not in the debugger loop.
  bool is_interrupted_;  // True if interrupt command is pending.

  DbgMessage* msglist_head_;  // Start of debugger messages list.
  DbgMessage* msglist_tail_;  // End of debugger messages list.

  // Text buffer that accumulates messages to be output.
  dart::TextBuffer queued_output_messages_;

  Dart_IsolateId isolate_id_;  // Id of the isolate tied to this queue.

  DbgMsgQueue* next_;  // Used for creating a list of message queues.

  // The isolate waits on this condition variable when it needs to process
  // debug messages.
  dart::Monitor msg_queue_lock_;

  DISALLOW_COPY_AND_ASSIGN(DbgMsgQueue);
};


// Maintains a list of message queues.
class DbgMsgQueueList {
 public:
  static const int32_t kInvalidCommand = -1;

  // Initialize the message queue processing by setting up the appropriate
  // handlers.
  static void Initialize();

  // Parses the input message and returns the command index if the message
  // contains a valid isolate specific command.
  // It returns kInvalidCommand otherwise.
  static int32_t LookupIsolateCommand(const char* buf, int32_t buflen);

  // Queue debugger message targetted for the isolate.
  static bool AddIsolateMessage(Dart_IsolateId isolate_id,
                                int32_t cmd_idx,
                                const char* start,
                                const char* end,
                                int debug_fd);

  // Notify an isolate of a pending vmservice message.
  static void NotifyIsolate(Dart_Isolate isolate);

  // Interrupt isolate.
  static bool InterruptIsolate(Dart_IsolateId isolate_id);

  // Add Debugger Message Queue corresponding to the Isolate.
  static DbgMsgQueue* AddIsolateMsgQueue(Dart_IsolateId isolate_id);

  // Get Debugger Message Queue corresponding to the Isolate.
  static DbgMsgQueue* GetIsolateMsgQueue(Dart_IsolateId isolate_id);

  // Remove Debugger Message Queue corresponding to the Isolate.
  static void RemoveIsolateMsgQueue(Dart_IsolateId isolate_id);

  // Generic handlers for breakpoints, exceptions and delayed breakpoint
  // resolution.
  static void BptResolvedHandler(Dart_IsolateId isolate_id,
                                 intptr_t bp_id,
                                 const Dart_CodeLocation& location);
  static void PausedEventHandler(Dart_IsolateId isolate_id,
                                 intptr_t bp_id,
                                 const Dart_CodeLocation& loc);
  static void ExceptionThrownHandler(Dart_IsolateId isolate_id,
                                     Dart_Handle exception,
                                     Dart_StackTrace stack_trace);
  static void IsolateEventHandler(Dart_IsolateId isolate_id,
                                  Dart_IsolateEvent kind);

  // Print list of isolate ids of all message queues into text buffer.
  static void ListIsolateIds(dart::TextBuffer* msg);

 private:
  static DbgMsgQueue* GetIsolateMsgQueueLocked(Dart_IsolateId isolate_id);

  static DbgMsgQueue* list_;
  static dart::Mutex* msg_queue_list_lock_;

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(DbgMsgQueueList);
};

}  // namespace bin
}  // namespace dart

#endif  // BIN_DBG_MESSAGE_H_
