// Copyright (c) 2013, 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_SERVICE_H_
#define RUNTIME_VM_SERVICE_H_

#include <atomic>
#include <memory>

#include "include/dart_tools_api.h"

#include "vm/allocation.h"
#include "vm/object_id_ring.h"
#include "vm/os_thread.h"
#include "vm/tagged_pointer.h"
#include "vm/thread.h"

namespace dart {

#define SERVICE_PROTOCOL_MAJOR_VERSION 4
#define SERVICE_PROTOCOL_MINOR_VERSION 16

class Array;
class EmbedderServiceHandler;
class Error;
class GCEvent;
class GrowableObjectArray;
class Instance;
class Isolate;
class IsolateGroup;
class JSONStream;
class JSONObject;
class Object;
class ServiceEvent;
class String;

class ServiceIdZone {
 public:
  ServiceIdZone(intptr_t id, ObjectIdRing::IdPolicy policy);
  virtual ~ServiceIdZone();

  // Parses a Service ID zone ID string and returns the corresponding integer
  // ID. Or, returns -1 if |id_string| is invalid.
  //
  // For example, this function will return 5 when called with the argument
  // "zones/5".
  intptr_t static StringIdToInt(const char* id_string);

  intptr_t id() const { return id_; }
  ObjectIdRing::IdPolicy policy() const { return policy_; }

  virtual int32_t GetIdForObject(const ObjectPtr obj) = 0;
  virtual ObjectPtr GetObjectForId(int32_t id,
                                   ObjectIdRing::LookupResult* kind) = 0;
  // Returned string will be zone allocated.
  virtual char* GetServiceId(const Object& obj) = 0;
  // Invalidate all the Service IDs currently living in this zone.
  virtual void Invalidate() = 0;
  virtual void VisitPointers(ObjectPointerVisitor& visitor) const = 0;

  virtual void PrintJSON(JSONStream& js) const = 0;

 private:
  intptr_t id_;
  ObjectIdRing::IdPolicy policy_;

  friend class ServiceIdZonePolicyOverrideScope;
};

#define ISOLATE_SERVICE_ID_FORMAT_STRING "isolates/%" Pd64 ""
#define ISOLATE_GROUP_SERVICE_ID_PREFIX "isolateGroups/"
#define ISOLATE_GROUP_SERVICE_ID_FORMAT_STRING                                 \
  ISOLATE_GROUP_SERVICE_ID_PREFIX "%" Pu64 ""

class RingServiceIdZone final : public ServiceIdZone {
 public:
  // The capacity of the default Service ID zone of each isolate.
  static constexpr int32_t kCapacityOfDefaultIdZone = 8192;
  // The fallback capacity used when the `createIdZone` Service procedure is
  // called without a `capacity` argument.
  static constexpr int32_t kFallbackCapacityForCreateIdZone = 512;

  RingServiceIdZone(intptr_t id,
                    ObjectIdRing::IdPolicy policy,
                    int32_t capacity);
  ~RingServiceIdZone() final;

  int32_t GetIdForObject(const ObjectPtr obj) final;
  ObjectPtr GetObjectForId(int32_t id, ObjectIdRing::LookupResult* kind) final;
  // Returned string will be zone allocated.
  char* GetServiceId(const Object& obj) final;
  void Invalidate() final;
  void VisitPointers(ObjectPointerVisitor& visitor) const final;

  void PrintJSON(JSONStream& js) const final;

 private:
  ObjectIdRing ring_;
};

class StreamInfo {
 public:
  explicit StreamInfo(const char* id)
      : id_(id), enabled_(0), include_private_members_(false) {}

  const char* id() const { return id_; }

  void set_enabled(bool value) { enabled_ = value ? 1 : 0; }
  bool enabled() const { return enabled_ != 0; }

  void set_include_private_members(bool value) {
    include_private_members_ = value;
  }
  bool include_private_members() const { return include_private_members_; }

  // This may get access by multiple threads, but relaxed access is ok.
  static intptr_t enabled_offset() { return OFFSET_OF(StreamInfo, enabled_); }

 private:
  const char* id_;
  std::atomic<intptr_t> enabled_;
  std::atomic<bool> include_private_members_;
};

class Service : public AllStatic {
 public:
  static void Init();
  static void Cleanup();

  // Handles a message which is not directed to an isolate.
  static ErrorPtr HandleRootMessage(const Array& message);

  // Handles a message which is not directed to an isolate and also
  // expects the parameter keys and values to be actual dart objects.
  static ErrorPtr HandleObjectRootMessage(const Array& message);

  // Handles a message which is directed to a particular isolate.
  static ErrorPtr HandleIsolateMessage(Isolate* isolate, const Array& message);

  static void HandleEvent(ServiceEvent* event, bool enter_safepoint = true);

  static void RegisterIsolateEmbedderCallback(
      const char* name,
      Dart_ServiceRequestCallback callback,
      void* user_data);

  static void RegisterRootEmbedderCallback(const char* name,
                                           Dart_ServiceRequestCallback callback,
                                           void* user_data);

  static void SetEmbedderInformationCallback(
      Dart_EmbedderInformationCallback callback);

  static void SetEmbedderStreamCallbacks(
      Dart_ServiceStreamListenCallback listen_callback,
      Dart_ServiceStreamCancelCallback cancel_callback);

  static void SetGetServiceAssetsCallback(
      Dart_GetVMServiceAssetsArchive get_service_assets);

  static void SendEchoEvent(Isolate* isolate, const char* text);
  static void SendInspectEvent(Isolate* isolate, const Object& inspectee);

  static void SendEmbedderEvent(Isolate* isolate,
                                const char* stream_id,
                                const char* event_kind,
                                const uint8_t* bytes,
                                intptr_t bytes_len);

  static void SendLogEvent(Isolate* isolate,
                           int64_t sequence_number,
                           int64_t timestamp,
                           intptr_t level,
                           const String& name,
                           const String& message,
                           const Instance& zone,
                           const Object& error,
                           const Instance& stack_trace);

  static void SendExtensionEvent(Isolate* isolate,
                                 const String& event_kind,
                                 const String& event_data);

  // Takes ownership of 'data'.
  static void SendEventWithData(const char* stream_id,
                                const char* event_type,
                                intptr_t reservation,
                                const char* metadata,
                                intptr_t metadata_size,
                                uint8_t* data,
                                intptr_t data_size);

  static void PostError(const String& method_name,
                        const Array& parameter_keys,
                        const Array& parameter_values,
                        const Instance& reply_port,
                        const Instance& id,
                        const Error& error);

  // Logs the size of the contents of `js` to FLAG_log_service_response_sizes.
  static void LogResponseSize(const char* method, JSONStream* js);

  // Enable/Disable timeline categories.
  // Returns True if the categories were successfully enabled, False otherwise.
  static bool EnableTimelineStreams(char* categories_list);

  // Well-known streams.
  static StreamInfo vm_stream;
  static StreamInfo isolate_stream;
  static StreamInfo debug_stream;
  static StreamInfo gc_stream;
  static StreamInfo echo_stream;
  static StreamInfo heapsnapshot_stream;
  static StreamInfo logging_stream;
  static StreamInfo extension_stream;
  static StreamInfo timeline_stream;
  static StreamInfo profiler_stream;

  static bool ListenStream(const char* stream_id, bool include_privates);
  static void CancelStream(const char* stream_id);

  static ObjectPtr RequestAssets();

  static Dart_ServiceStreamListenCallback stream_listen_callback() {
    return stream_listen_callback_;
  }
  static Dart_ServiceStreamCancelCallback stream_cancel_callback() {
    return stream_cancel_callback_;
  }

  static void PrintJSONForEmbedderInformation(JSONObject* jsobj);
  static void PrintJSONForVM(JSONStream* js, bool ref);

  static void CheckForPause(Isolate* isolate, JSONStream* stream);

  static int64_t CurrentRSS();
  static int64_t MaxRSS();

  static void SetDartLibraryKernelForSources(const uint8_t* kernel_bytes,
                                             intptr_t kernel_length);
  static bool HasDartLibraryKernelForSources() {
    return (dart_library_kernel_ != nullptr);
  }

  static const uint8_t* dart_library_kernel() { return dart_library_kernel_; }

  static intptr_t dart_library_kernel_length() {
    return dart_library_kernel_len_;
  }

 private:
  static ErrorPtr InvokeMethod(Isolate* isolate,
                               const Array& message,
                               bool parameters_are_dart_objects = false);

  static void EmbedderHandleMessage(EmbedderServiceHandler* handler,
                                    JSONStream* js);

  static EmbedderServiceHandler* FindIsolateEmbedderHandler(const char* name);
  static EmbedderServiceHandler* FindRootEmbedderHandler(const char* name);
  static void ScheduleExtensionHandler(const Instance& handler,
                                       const String& method_name,
                                       const Array& parameter_keys,
                                       const Array& parameter_values,
                                       const Instance& reply_port,
                                       const Instance& id);

  // Takes ownership of 'bytes'.
  static void SendEvent(const char* stream_id,
                        const char* event_type,
                        uint8_t* bytes,
                        intptr_t bytes_length);

  static void PostEvent(IsolateGroup* isolate_group,
                        Isolate* isolate,
                        const char* stream_id,
                        const char* kind,
                        JSONStream* event,
                        bool enter_safepoint);

  static void PostEventImpl(IsolateGroup* isolate_group,
                            Isolate* isolate,
                            const char* stream_id,
                            const char* kind,
                            JSONStream* event);

  static ErrorPtr MaybePause(Isolate* isolate, const Error& error);

  static EmbedderServiceHandler* isolate_service_handler_head_;
  static EmbedderServiceHandler* root_service_handler_head_;
  static Dart_ServiceStreamListenCallback stream_listen_callback_;
  static Dart_ServiceStreamCancelCallback stream_cancel_callback_;
  static Dart_GetVMServiceAssetsArchive get_service_assets_callback_;
  static Dart_EmbedderInformationCallback embedder_information_callback_;

  static void* service_response_size_log_file_;

  static const uint8_t* dart_library_kernel_;
  static intptr_t dart_library_kernel_len_;
};

// Visible for testing.
intptr_t ParseJSONArray(Thread* thread,
                        const char* str,
                        const GrowableObjectArray& elements);

}  // namespace dart

#endif  // RUNTIME_VM_SERVICE_H_
