// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_RUNTIME_DART_ISOLATE_H_
#define FLUTTER_RUNTIME_DART_ISOLATE_H_

#include <memory>
#include <set>
#include <string>

#include "flutter/common/task_runners.h"
#include "flutter/fml/compiler_specific.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/mapping.h"
#include "flutter/lib/ui/hint_freed_delegate.h"
#include "flutter/lib/ui/io_manager.h"
#include "flutter/lib/ui/snapshot_delegate.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/runtime/dart_snapshot.h"
#include "third_party/dart/runtime/include/dart_api.h"
#include "third_party/tonic/dart_state.h"

namespace flutter {

class DartVM;
class DartIsolateGroupData;

//------------------------------------------------------------------------------
/// @brief      Represents an instance of a live isolate. An isolate is a
///             separate Dart execution context. Different Dart isolates don't
///             share memory and can be scheduled concurrently by the Dart VM on
///             one of the Dart VM managed worker pool threads.
///
///             The entire lifecycle of a Dart isolate is controlled by the Dart
///             VM. Because of this, the engine never holds a strong pointer to
///             the Dart VM for extended periods of time. This allows the VM (or
///             the isolates themselves) to terminate Dart execution without
///             consulting the engine.
///
///             The isolate that the engine creates to act as the host for the
///             Flutter application code with UI bindings is called the root
///             isolate.
///
///             The root isolate is special in the following ways:
///             * The root isolate forms a new isolate group. Child isolates are
///               added to their parents groups. When the root isolate dies, all
///               isolates in its group are terminated.
///             * Only root isolates get UI bindings.
///             * Root isolates execute their code on engine managed threads.
///               All other isolates run their Dart code on Dart VM managed
///               thread pool workers that the engine has no control over.
///             * Since the engine does not know the thread on which non-root
///               isolates are run, the engine has no opportunity to get a
///               reference to non-root isolates. Such isolates can only be
///               terminated if they terminate themselves or their isolate group
///               is torn down.
///
class DartIsolate : public UIDartState {
 public:
  //----------------------------------------------------------------------------
  /// @brief      The engine represents all dart isolates as being in one of the
  ///             known phases. By invoking various methods on the Dart isolate,
  ///             the engine transition the Dart isolate from one phase to the
  ///             next. The Dart isolate will only move from one phase to the
  ///             next in the order specified in the `DartIsolate::Phase` enum.
  ///             That is, once the isolate has moved out of a particular phase,
  ///             it can never transition back to that phase in the future.
  ///             There is no error recovery mechanism and callers that find
  ///             their isolates in an undesirable phase must discard the
  ///             isolate and start over.
  ///
  enum class Phase {
    //--------------------------------------------------------------------------
    /// The initial phase of all Dart isolates. This is an internal phase and
    /// callers can never get a reference to a Dart isolate in this phase.
    ///
    Unknown,
    //--------------------------------------------------------------------------
    /// The Dart isolate has been created but none of the library tag or message
    /// handers have been set yet. The is an internal phase and callers can
    /// never get a reference to a Dart isolate in this phase.
    ///
    Uninitialized,
    //--------------------------------------------------------------------------
    /// The Dart isolate has been been fully initialized but none of the
    /// libraries referenced by that isolate have been loaded yet. This is an
    /// internal phase and callers can never get a reference to a Dart isolate
    /// in this phase.
    ///
    Initialized,
    //--------------------------------------------------------------------------
    /// The isolate has been fully initialized and is waiting for the caller to
    /// associate isolate snapshots with the same. The isolate will only be
    /// ready to execute Dart code once one of the `Prepare` calls are
    /// successfully made.
    ///
    LibrariesSetup,
    //--------------------------------------------------------------------------
    /// The isolate is fully ready to start running Dart code. Callers can
    /// transition the isolate to the next state by calling the `Run` or
    /// `RunFromLibrary` methods.
    ///
    Ready,
    //--------------------------------------------------------------------------
    /// The isolate is currently running Dart code.
    ///
    Running,
    //--------------------------------------------------------------------------
    /// The isolate is no longer running Dart code and is in the middle of being
    /// collected. This is in internal phase and callers can never get a
    /// reference to a Dart isolate in this phase.
    ///
    Shutdown,
  };

  //----------------------------------------------------------------------------
  /// @brief      Creates an instance of a root isolate and returns a weak
  ///             pointer to the same. The isolate instance may only be used
  ///             safely on the engine thread on which it was created. In the
  ///             shell, this is the UI thread and task runner. Using the
  ///             isolate on any other thread is user error.
  ///
  ///             The isolate that the engine creates to act as the host for the
  ///             Flutter application code with UI bindings is called the root
  ///             isolate.
  ///
  ///             The root isolate is special in the following ways:
  ///             * The root isolate forms a new isolate group. Child isolates
  ///               are added to their parents groups. When the root isolate
  ///               dies, all isolates in its group are terminated.
  ///             * Only root isolates get UI bindings.
  ///             * Root isolates execute their code on engine managed threads.
  ///               All other isolates run their Dart code on Dart VM managed
  ///               thread pool workers that the engine has no control over.
  ///             * Since the engine does not know the thread on which non-root
  ///               isolates are run, the engine has no opportunity to get a
  ///               reference to non-root isolates. Such isolates can only be
  ///               terminated if they terminate themselves or their isolate
  ///               group is torn down.
  ///
  /// @param[in]  settings                    The settings used to create the
  ///                                         isolate.
  /// @param[in]  isolate_snapshot            The isolate snapshot. This is
  ///                                         usually obtained from the
  ///                                         DartVMData associated with the
  ///                                         running Dart VM instance.
  /// @param[in]  task_runners                The task runners used by the
  ///                                         isolate. Via UI bindings, the
  ///                                         isolate will use the IO task
  ///                                         runner to scheduled texture
  ///                                         decompression jobs and post tasks
  ///                                         back to the UI task runner.
  /// @param[in]  window                      The weak pointer to the window
  ///                                         associated with this root isolate.
  /// @param[in]  io_manager                  The i/o manager.
  /// @param[in]  unref_queue                 The Skia unref queue.
  /// @param[in]  image_decoder               The image decoder.
  /// @param[in]  advisory_script_uri         The advisory script uri. This is
  ///                                         only used in instrumentation.
  /// @param[in]  advisory_script_entrypoint  The advisory script entrypoint.
  ///                                         This is only used in
  ///                                         instrumentation. Notably, this is
  ///                                         NOT the main entrypoint of Dart
  ///                                         code in the isolate. That is
  ///                                         specified when making one of the
  ///                                         `Run` calls.
  /// @param[in]  flags                       The Dart isolate flags for this
  ///                                         isolate instance.
  /// @param[in]  isolate_create_callback     The isolate create callback. This
  ///                                         will be called when the before the
  ///                                         main Dart entrypoint is invoked in
  ///                                         the root isolate. The isolate is
  ///                                         already in the running state at
  ///                                         this point and an isolate scope is
  ///                                         current.
  /// @param[in]  isolate_shutdown_callback   The isolate shutdown callback.
  ///                                         This will be called before the
  ///                                         isolate is about to transition
  ///                                         into the Shutdown phase. The
  ///                                         isolate is still running at this
  ///                                         point and an isolate scope is
  ///                                         current.
  ///
  /// @return     A weak pointer to the root Dart isolate. The caller must
  ///             ensure that the isolate is not referenced for long periods of
  ///             time as it prevents isolate collection when the isolate
  ///             terminates itself. The caller may also only use the isolate on
  ///             the thread on which the isolate was created.
  ///
  static std::weak_ptr<DartIsolate> CreateRootIsolate(
      const Settings& settings,
      fml::RefPtr<const DartSnapshot> isolate_snapshot,
      TaskRunners task_runners,
      std::unique_ptr<PlatformConfiguration> platform_configuration,
      fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
      fml::WeakPtr<HintFreedDelegate> hint_freed_delegate,
      fml::WeakPtr<IOManager> io_manager,
      fml::RefPtr<SkiaUnrefQueue> skia_unref_queue,
      fml::WeakPtr<ImageDecoder> image_decoder,
      std::string advisory_script_uri,
      std::string advisory_script_entrypoint,
      Dart_IsolateFlags* flags,
      const fml::closure& isolate_create_callback,
      const fml::closure& isolate_shutdown_callback);

  // |UIDartState|
  ~DartIsolate() override;

  //----------------------------------------------------------------------------
  /// @brief      The current phase of the isolate. The engine represents all
  ///             dart isolates as being in one of the known phases. By invoking
  ///             various methods on the Dart isolate, the engine transitions
  ///             the Dart isolate from one phase to the next. The Dart isolate
  ///             will only move from one phase to the next in the order
  ///             specified in the `DartIsolate::Phase` enum. That is, the once
  ///             the isolate has moved out of a particular phase, it can never
  ///             transition back to that phase in the future. There is no error
  ///             recovery mechanism and callers that find their isolates in an
  ///             undesirable phase must discard the isolate and start over.
  ///
  /// @return     The current isolate phase.
  ///
  Phase GetPhase() const;

  //----------------------------------------------------------------------------
  /// @brief      Returns the ID for an isolate which is used to query the
  ///             service protocol.
  ///
  /// @return     The service identifier for this isolate.
  ///
  std::string GetServiceId();

  //----------------------------------------------------------------------------
  /// @brief      Prepare the isolate for running for a precompiled code bundle.
  ///             The Dart VM must be configured for running precompiled code.
  ///
  ///             The isolate must already be in the `Phase::LibrariesSetup`
  ///             phase. After a successful call to this method, the isolate
  ///             will transition to the `Phase::Ready` phase.
  ///
  /// @return     Whether the isolate was prepared and the described phase
  ///             transition made.
  ///
  [[nodiscard]] bool PrepareForRunningFromPrecompiledCode();

  //----------------------------------------------------------------------------
  /// @brief      Prepare the isolate for running for a a list of kernel files.
  ///
  ///             The Dart VM must be configured for running from kernel
  ///             snapshots.
  ///
  ///             The isolate must already be in the `Phase::LibrariesSetup`
  ///             phase. This call can be made multiple times. After a series of
  ///             successful calls to this method, the caller can specify the
  ///             last kernel file mapping by specifying `last_piece` to `true`.
  ///             On success, the isolate will transition to the `Phase::Ready`
  ///             phase.
  ///
  /// @param[in]  kernel      The kernel mapping.
  /// @param[in]  last_piece  Indicates if this is the last kernel mapping
  ///                         expected. After this point, the isolate will
  ///                         attempt a transition to the `Phase::Ready` phase.
  ///
  /// @return     If the kernel mapping supplied was successfully used to
  ///             prepare the isolate.
  ///
  [[nodiscard]] bool PrepareForRunningFromKernel(
      std::shared_ptr<const fml::Mapping> kernel,
      bool last_piece = true);

  //----------------------------------------------------------------------------
  /// @brief      Prepare the isolate for running for a a list of kernel files.
  ///
  ///             The Dart VM must be configured for running from kernel
  ///             snapshots.
  ///
  ///             The isolate must already be in the `Phase::LibrariesSetup`
  ///             phase. After a successful call to this method, the isolate
  ///             will transition to the `Phase::Ready` phase.
  ///
  /// @param[in]  kernels  The kernels
  ///
  /// @return     If the kernel mappings supplied were successfully used to
  ///             prepare the isolate.
  ///
  [[nodiscard]] bool PrepareForRunningFromKernels(
      std::vector<std::shared_ptr<const fml::Mapping>> kernels);

  //----------------------------------------------------------------------------
  /// @brief      Prepare the isolate for running for a a list of kernel files.
  ///
  ///             The Dart VM must be configured for running from kernel
  ///             snapshots.
  ///
  ///             The isolate must already be in the `Phase::LibrariesSetup`
  ///             phase. After a successful call to this method, the isolate
  ///             will transition to the `Phase::Ready` phase.
  ///
  /// @param[in]  kernels  The kernels
  ///
  /// @return     If the kernel mappings supplied were successfully used to
  ///             prepare the isolate.
  ///
  [[nodiscard]] bool PrepareForRunningFromKernels(
      std::vector<std::unique_ptr<const fml::Mapping>> kernels);

  //----------------------------------------------------------------------------
  /// @brief      Transition the root isolate to the `Phase::Running` phase and
  ///             invoke the main entrypoint (the "main" method) in the root
  ///             library. The isolate must already be in the `Phase::Ready`
  ///             phase.
  ///
  /// @param[in]  entrypoint  The entrypoint in the root library.
  /// @param[in]  args        A list of string arguments to the entrypoint.
  /// @param[in]  on_run      A callback to run in isolate scope after the main
  ///                         entrypoint has been invoked. There is no isolate
  ///                         scope current on the thread once this method
  ///                         returns.
  ///
  /// @return     If the isolate successfully transitioned to the running phase
  ///             and the main entrypoint was invoked.
  ///
  [[nodiscard]] bool Run(const std::string& entrypoint,
                         const std::vector<std::string>& args,
                         const fml::closure& on_run = nullptr);

  //----------------------------------------------------------------------------
  /// @brief      Transition the root isolate to the `Phase::Running` phase and
  ///             invoke the main entrypoint (the "main" method) in the
  ///             specified library. The isolate must already be in the
  ///             `Phase::Ready` phase.
  ///
  /// @param[in]  library_name  The name of the library in which to invoke the
  ///                           supplied entrypoint.
  /// @param[in]  entrypoint    The entrypoint in `library_name`
  /// @param[in]  args          A list of string arguments to the entrypoint.
  /// @param[in]  on_run        A callback to run in isolate scope after the
  ///                           main entrypoint has been invoked. There is no
  ///                           isolate scope current on the thread once this
  ///                           method returns.
  ///
  /// @return     If the isolate successfully transitioned to the running phase
  ///             and the main entrypoint was invoked.
  ///
  [[nodiscard]] bool RunFromLibrary(const std::string& library_name,
                                    const std::string& entrypoint,
                                    const std::vector<std::string>& args,
                                    const fml::closure& on_run = nullptr);

  //----------------------------------------------------------------------------
  /// @brief      Transition the isolate to the `Phase::Shutdown` phase. The
  ///             only thing left to do is to collect the isolate.
  ///
  /// @return     If the isolate succesfully transitioned to the shutdown phase.
  ///
  [[nodiscard]] bool Shutdown();

  //----------------------------------------------------------------------------
  /// @brief      Registers a callback that will be invoked in isolate scope
  ///             just before the isolate transitions to the `Phase::Shutdown`
  ///             phase.
  ///
  /// @param[in]  closure  The callback to invoke on isolate shutdown.
  ///
  void AddIsolateShutdownCallback(const fml::closure& closure);

  //----------------------------------------------------------------------------
  /// @brief      A weak pointer to the Dart isolate instance. This instance may
  ///             only be used on the task runner that created the root isolate.
  ///
  /// @return     The weak isolate pointer.
  ///
  std::weak_ptr<DartIsolate> GetWeakIsolatePtr();

  //----------------------------------------------------------------------------
  /// @brief      The task runner on which the Dart code for the root isolate is
  ///             running. For the root isolate, this is the UI task runner for
  ///             the shell that owns the root isolate.
  ///
  /// @return     The message handling task runner.
  ///
  fml::RefPtr<fml::TaskRunner> GetMessageHandlingTaskRunner() const;

 private:
  class AutoFireClosure {
   public:
    AutoFireClosure(const fml::closure& closure);

    ~AutoFireClosure();

   private:
    fml::closure closure_;
    FML_DISALLOW_COPY_AND_ASSIGN(AutoFireClosure);
  };
  friend class DartVM;

  Phase phase_ = Phase::Unknown;
  std::vector<std::shared_ptr<const fml::Mapping>> kernel_buffers_;
  std::vector<std::unique_ptr<AutoFireClosure>> shutdown_callbacks_;
  fml::RefPtr<fml::TaskRunner> message_handling_task_runner_;
  const bool may_insecurely_connect_to_all_domains_;
  std::string domain_network_policy_;

  DartIsolate(const Settings& settings,
              TaskRunners task_runners,
              fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
              fml::WeakPtr<HintFreedDelegate> hint_freed_delegate,
              fml::WeakPtr<IOManager> io_manager,
              fml::RefPtr<SkiaUnrefQueue> unref_queue,
              fml::WeakPtr<ImageDecoder> image_decoder,
              std::string advisory_script_uri,
              std::string advisory_script_entrypoint,
              bool is_root_isolate);
  [[nodiscard]] bool Initialize(Dart_Isolate isolate);

  void SetMessageHandlingTaskRunner(fml::RefPtr<fml::TaskRunner> runner);

  bool LoadKernel(std::shared_ptr<const fml::Mapping> mapping, bool last_piece);

  [[nodiscard]] bool LoadLibraries();

  bool UpdateThreadPoolNames() const;

  [[nodiscard]] bool MarkIsolateRunnable();

  void OnShutdownCallback();

  DartIsolateGroupData& GetIsolateGroupData();

  // |Dart_IsolateGroupCreateCallback|
  static Dart_Isolate DartIsolateGroupCreateCallback(
      const char* advisory_script_uri,
      const char* advisory_script_entrypoint,
      const char* package_root,
      const char* package_config,
      Dart_IsolateFlags* flags,
      std::shared_ptr<DartIsolate>* parent_isolate_group,
      char** error);

  // |Dart_IsolateInitializeCallback|
  static bool DartIsolateInitializeCallback(void** child_callback_data,
                                            char** error);

  static Dart_Isolate DartCreateAndStartServiceIsolate(
      const char* package_root,
      const char* package_config,
      Dart_IsolateFlags* flags,
      char** error);

  static Dart_Isolate CreateDartIsolateGroup(
      std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
      std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
      Dart_IsolateFlags* flags,
      char** error);

  static bool InitializeIsolate(std::shared_ptr<DartIsolate> embedder_isolate,
                                Dart_Isolate isolate,
                                char** error);

  // |Dart_IsolateShutdownCallback|
  static void DartIsolateShutdownCallback(
      std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
      std::shared_ptr<DartIsolate>* isolate_data);

  // |Dart_IsolateCleanupCallback|
  static void DartIsolateCleanupCallback(
      std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
      std::shared_ptr<DartIsolate>* isolate_data);

  // |Dart_IsolateGroupCleanupCallback|
  static void DartIsolateGroupCleanupCallback(
      std::shared_ptr<DartIsolateGroupData>* isolate_group_data);

  FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate);
};

}  // namespace flutter

#endif  // FLUTTER_RUNTIME_DART_ISOLATE_H_
