// 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_DART_H_
#define RUNTIME_VM_DART_H_

#include "include/dart_api.h"
#include "include/dart_tools_api.h"
#include "vm/allocation.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/os_thread.h"
#include "vm/snapshot.h"

namespace dart {

// Forward declarations.
class DebugInfo;
class Isolate;
class LocalHandle;
class ReadOnlyHandles;
class ThreadPool;
namespace kernel {
class Program;
}

class Dart : public AllStatic {
 public:
  // Returns null if initialization succeeds, otherwise returns an error message
  // (caller owns error message and has to free it).
  static char* Init(const Dart_InitializeParams* params);

  // Returns null if cleanup succeeds, otherwise returns an error message
  // (caller owns error message and has to free it).
  static char* Cleanup();

  // Returns true if the VM is initialized.
  static bool IsInitialized();

  // Used to Indicate that a Dart API call is active.
  static bool SetActiveApiCall();
  static void ResetActiveApiCall();

  static Isolate* CreateIsolate(const char* name_prefix,
                                const Dart_IsolateFlags& api_flags,
                                IsolateGroup* isolate_group);

  // Initialize an isolate, either from a snapshot, from a Kernel binary, or
  // from SDK library sources.  If the snapshot_buffer is non-NULL,
  // initialize from a snapshot or a Kernel binary depending on the value of
  // from_kernel.  Otherwise, initialize from sources.
  static ErrorPtr InitializeIsolate(const uint8_t* snapshot_data,
                                    const uint8_t* snapshot_instructions,
                                    const uint8_t* kernel_buffer,
                                    intptr_t kernel_buffer_size,
                                    IsolateGroup* source_isolate_group,
                                    void* data);
  static ErrorPtr InitIsolateFromSnapshot(Thread* T,
                                          Isolate* I,
                                          const uint8_t* snapshot_data,
                                          const uint8_t* snapshot_instructions,
                                          const uint8_t* kernel_buffer,
                                          intptr_t kernel_buffer_size);

  static bool DetectNullSafety(const char* script_uri,
                               const uint8_t* snapshot_data,
                               const uint8_t* snapshot_instructions,
                               const uint8_t* kernel_buffer,
                               intptr_t kernel_buffer_size,
                               const char* package_config,
                               const char* original_working_directory);

  static void RunShutdownCallback();
  static void ShutdownIsolate(Isolate* isolate);
  static void ShutdownIsolate();

  static Isolate* vm_isolate() { return vm_isolate_; }
  static IsolateGroup* vm_isolate_group() { return vm_isolate_->group(); }
  static ThreadPool* thread_pool() { return thread_pool_; }
  static bool VmIsolateNameEquals(const char* name);

  static int64_t UptimeMicros();
  static int64_t UptimeMillis() {
    return UptimeMicros() / kMicrosecondsPerMillisecond;
  }

  static void set_pprof_symbol_generator(DebugInfo* value) {
    pprof_symbol_generator_ = value;
  }
  static DebugInfo* pprof_symbol_generator() { return pprof_symbol_generator_; }

  static LocalHandle* AllocateReadOnlyApiHandle();
  static bool IsReadOnlyApiHandle(Dart_Handle handle);

  static uword AllocateReadOnlyHandle();
  static bool IsReadOnlyHandle(uword address);

  // The returned string has to be free()ed.
  static char* FeaturesString(IsolateGroup* isolate_group,
                              bool is_vm_snapshot,
                              Snapshot::Kind kind);
  static Snapshot::Kind vm_snapshot_kind() { return vm_snapshot_kind_; }

  static Dart_ThreadStartCallback thread_start_callback() {
    return thread_start_callback_;
  }
  static void set_thread_start_callback(Dart_ThreadStartCallback cback) {
    thread_start_callback_ = cback;
  }
  static Dart_ThreadExitCallback thread_exit_callback() {
    return thread_exit_callback_;
  }
  static void set_thread_exit_callback(Dart_ThreadExitCallback cback) {
    thread_exit_callback_ = cback;
  }
  static Dart_PostTaskCallback post_task_callback() {
    return post_task_callback_;
  }
  static void set_post_task_callback(Dart_PostTaskCallback cback) {
    post_task_callback_ = cback;
  }
  static void* post_task_data() { return post_task_data_; }
  static void set_post_task_data(void* data) { post_task_data_ = data; }
  static void SetFileCallbacks(Dart_FileOpenCallback file_open,
                               Dart_FileReadCallback file_read,
                               Dart_FileWriteCallback file_write,
                               Dart_FileCloseCallback file_close) {
    file_open_callback_ = file_open;
    file_read_callback_ = file_read;
    file_write_callback_ = file_write;
    file_close_callback_ = file_close;
  }

  static Dart_FileOpenCallback file_open_callback() {
    return file_open_callback_;
  }
  static Dart_FileReadCallback file_read_callback() {
    return file_read_callback_;
  }
  static Dart_FileWriteCallback file_write_callback() {
    return file_write_callback_;
  }
  static Dart_FileCloseCallback file_close_callback() {
    return file_close_callback_;
  }

  static void set_entropy_source_callback(Dart_EntropySource entropy_source) {
    entropy_source_callback_ = entropy_source;
  }
  static Dart_EntropySource entropy_source_callback() {
    return entropy_source_callback_;
  }

  static void set_gc_event_callback(Dart_GCEventCallback gc_event) {
    gc_event_callback_ = gc_event;
  }
  static Dart_GCEventCallback gc_event_callback() { return gc_event_callback_; }

 private:
  static char* DartInit(const Dart_InitializeParams* params);

  static constexpr const char* kVmIsolateName = "vm-isolate";

  static void WaitForIsolateShutdown();
  static void WaitForApplicationIsolateShutdown();

  static Isolate* vm_isolate_;
  static int64_t start_time_micros_;
  static ThreadPool* thread_pool_;
  static DebugInfo* pprof_symbol_generator_;
  static ReadOnlyHandles* predefined_handles_;
  static Snapshot::Kind vm_snapshot_kind_;
  static Dart_ThreadStartCallback thread_start_callback_;
  static Dart_ThreadExitCallback thread_exit_callback_;
  static Dart_FileOpenCallback file_open_callback_;
  static Dart_FileReadCallback file_read_callback_;
  static Dart_FileWriteCallback file_write_callback_;
  static Dart_FileCloseCallback file_close_callback_;
  static Dart_EntropySource entropy_source_callback_;
  static Dart_GCEventCallback gc_event_callback_;
  static Dart_PostTaskCallback post_task_callback_;
  static void* post_task_data_;
};

}  // namespace dart

#endif  // RUNTIME_VM_DART_H_
