// Copyright (c) 2025, 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_ENGINE_INCLUDE_DART_ENGINE_H_
#define RUNTIME_ENGINE_INCLUDE_DART_ENGINE_H_
#include "include/dart_api.h"

/**
 * Initializes the Dart engine.
 *
 * \param[out] error Set to NULL if initialization was successful.
 *    Otherwise is set to a description of error which occurred during
 *    initialization. The caller is responsible for freeing the error string.
 *
 * \return true if initialization is successful and false otherwise.
 */
DART_EXPORT bool DartEngine_Init(char** error);

/**
 * Shuts down the Dart engine.
 *
 * Stops all isolates and frees all resources.
 */
DART_EXPORT void DartEngine_Shutdown();

/**
 * Kind of a snapshot represented by DartEngine_SnapshotData.
 */
typedef enum {
  DartEngine_SnapshotKind_Kernel,
  DartEngine_SnapshotKind_AOT,
} DartEngine_SnapshotKind;

/**
 * Dart snapshot data, sufficient to create an isolate.
 */
typedef struct DartEngine_SnapshotData {
  /**
   * Uniquely identifies a snapshot.
   *
   * It is passed to \ref Dart_CreateIsolateGroup or
   * \ref Dart_CreateIsolateGroupFromKernel.
   */
  const char* script_uri;
  /**
   * Whether this snapshot data reprents Kernel or AOT snapshot.
   */
  DartEngine_SnapshotKind kind;
  union {
    struct {
      const uint8_t* kernel_buffer;
      intptr_t kernel_buffer_size;
    };
    struct {
      const uint8_t* vm_snapshot_data;
      const uint8_t* vm_snapshot_instructions;
      const uint8_t* vm_isolate_data;
      const uint8_t* vm_isolate_instructions;
    };
  };
} DartEngine_SnapshotData;

/**
 * Creates a new isolate for a given snapshot.
 *
 * \param snapshot_data Snapshot to start an isolate from.
 * \param[out] error Set to NULL if an isolate is created successfully.
 *    Otherwise is set to a description of error which occurred during
 *    isolate creation. The caller is responsible for freeing the error string.
 *
 * \return The new isolate on success, or NULL if isolate creation failed.
 */
DART_EXPORT Dart_Isolate
DartEngine_CreateIsolate(DartEngine_SnapshotData snapshot_data, char** error);

/**
 * Blocks until the isolate is available for entering and enters an isolate.
 *
 * This is an alternative to \ref Dart_EnterIsolate, which can be used when
 * multiple threads may try to enter the same isolate at the same time.
 *
 * Use \ref DartEngine_ReleaseIsolate instead of `Dart_ExitIsolate` if you
 * use this function.
 */
DART_EXPORT void DartEngine_AcquireIsolate(Dart_Isolate isolate);

/**
 * Exits an isolate and makes it available for entering by other threads.
 *
 * This is an alternative to \ref Dart_ExitIsolate, which should be used
 * if you use \ref DartEngine_AcquireIsolate.
 */
DART_EXPORT void DartEngine_ReleaseIsolate();

/**
 * A callback invoked when there's an error handling isolate message.
 *
 * \param error Dart error happened during handling a message.
 * \param destination_isolate The isolate where the error occurred.
 */
typedef void (*DartEngine_HandleMessageErrorCallback)(
    Dart_Handle error,
    Dart_Isolate destination_isolate);

/**
 * Sets the callback for errors during handling isolate messages.
 */
DART_EXPORT void DartEngine_SetHandleMessageErrorCallback(
    DartEngine_HandleMessageErrorCallback handle_message_error_callback);

/**
 * Drains the microtasks queue. Requires to be an active isolate.
 *
 * Normally the microtasks queue is drained after handling each
 * isolate message, but when the engine calls into Dart, it might be
 * required to manually drain the microtasks queue.
 *
 * If a microtask throws, the error is returned to the caller,
 * and the queue may still contain more entries.
 * The caller should continue to drain the queue after handling the error.
 *
 * \return Dart_Handle invocation result.
 */
DART_EXPORT Dart_Handle DartEngine_DrainMicrotasksQueue();

/**
 * Handles a single message for an isolate.
 */
DART_EXPORT void DartEngine_HandleMessage(Dart_Isolate isolate);

/**
 * Message scheduling callback.
 *
 * Dart Engine calls this callback whenever there's a new message for an
 * isolate, and the callback should schedule an execution of
 * DartEngine_HandleMessage with given isolate.
 *
 * \param isolate Destination isolate for a mesage.
 * \param context Context from \ref DartEngine_MessageScheduler.
 */
typedef void (*DartEngine_ScheduleMessageCallback)(Dart_Isolate isolate,
                                                   void* context);

/**
 * Scheduler for isolate messages.
 *
 * Whenever Dart isolate has a new message, the Dart engine will
 * call schedule_callback and pass context into it.
 */
typedef struct DartEngine_MessageScheduler {
  DartEngine_ScheduleMessageCallback schedule_callback;
  void* context;
} DartEngine_MessageScheduler;

/**
 * Sets default message scheduler for all isolates.
 */
DART_EXPORT void DartEngine_SetDefaultMessageScheduler(
    DartEngine_MessageScheduler scheduler);

/**
 * Sets message scheduler for isolate.
 */
DART_EXPORT void DartEngine_SetMessageScheduler(
    DartEngine_MessageScheduler scheduler,
    Dart_Isolate isolate);

/**
 * Loads \ref DartEngine_SnapshotData from file
 *
 * User should not free uri and buffer.
 *
 * \param[out] error Set to NULL if snapshot could be loaded successfully.
 *    Otherwise is set to a description of error which occurred during
 *    snapshot loading. The caller is responsible for freeing the error string.
 *
 * \return Snapshot data with kind set to \ref DartEngine_SnapshotKind_Kernel.
 */
DART_EXPORT DartEngine_SnapshotData DartEngine_KernelFromFile(const char* path,
                                                              char** error);
/**
 * Loads \ref DartEngine_SnapshotData from file
 *
 * User should not free uri and buffers.
 *
 * \param[out] error Set to NULL if snapshot could be loaded successfully.
 *    Otherwise is set to a description of error which occurred during
 *    snapshot loading. The caller is responsible for freeing the error string.
 *
 * \return Snapshot data with kind set to \ref DartEngine_SnapshotKind_AOT.
 */
DART_EXPORT DartEngine_SnapshotData
DartEngine_AotSnapshotFromFile(const char* path, char** error);

#endif  // RUNTIME_ENGINE_INCLUDE_DART_ENGINE_H_
