// 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 <optional>
#include <set>
#include <string>
#include <unordered_set>

#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/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;
class IsolateConfiguration;

//------------------------------------------------------------------------------
/// @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:
  class Flags {
   public:
    Flags();

    explicit Flags(const Dart_IsolateFlags* flags);

    ~Flags();

    void SetNullSafetyEnabled(bool enabled);
    void SetIsDontNeedSafe(bool value);

    Dart_IsolateFlags Get() const;

   private:
    Dart_IsolateFlags flags_;
  };

  //----------------------------------------------------------------------------
  /// @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 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]  platform_configuration      The platform configuration for
  ///                                         handling communication with the
  ///                                         framework.
  /// @param[in]  flags                       The Dart isolate flags for this
  ///                                         isolate instance.
  /// @param[in]  dart_entrypoint             The name of the dart entrypoint
  ///                                         function to invoke.
  /// @param[in]  dart_entrypoint_library     The name of the dart library
  ///                                         containing the entrypoint.
  /// @param[in]  dart_entrypoint_args        Arguments passed as a List<String>
  ///                                         to Dart's entrypoint function.
  /// @param[in]  isolate_configuration       The isolate configuration used to
  ///                                         configure the isolate before
  ///                                         invoking the entrypoint.
  /// @param[in]  root_isolate_create_callback  A callback called after the root
  ///                                         isolate is created, _without_
  ///                                         isolate scope. This gives the
  ///                                         caller a chance to finish any
  ///                                         setup before running the Dart
  ///                                         program, and after any embedder
  ///                                         callbacks in the settings object.
  /// @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.
  /// @param[in]  context                     Engine-owned state which is
  ///                                         accessed by the root dart isolate.
  /// @param[in]  spawning_isolate            The isolate that is spawning the
  ///                                         new isolate.
  /// @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> CreateRunningRootIsolate(
      const Settings& settings,
      const fml::RefPtr<const DartSnapshot>& isolate_snapshot,
      std::unique_ptr<PlatformConfiguration> platform_configuration,
      Flags flags,
      const fml::closure& root_isolate_create_callback,
      const fml::closure& isolate_create_callback,
      const fml::closure& isolate_shutdown_callback,
      std::optional<std::string> dart_entrypoint,
      std::optional<std::string> dart_entrypoint_library,
      const std::vector<std::string>& dart_entrypoint_args,
      std::unique_ptr<IsolateConfiguration> isolate_configuration,
      const UIDartState::Context& context,
      const DartIsolate* spawning_isolate = nullptr);

  // |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(
      const std::shared_ptr<const fml::Mapping>& kernel,
      bool child_isolate,
      bool last_piece);

  //----------------------------------------------------------------------------
  /// @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
  ///             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.
  ///
  /// @return     If the isolate successfully transitioned to the running phase
  ///             and the main entrypoint was invoked.
  ///
  [[nodiscard]] bool RunFromLibrary(std::optional<std::string> library_name,
                                    std::optional<std::string> entrypoint,
                                    const std::vector<std::string>& args);

  //----------------------------------------------------------------------------
  /// @brief      Transition the isolate to the `Phase::Shutdown` phase. The
  ///             only thing left to do is to collect the isolate.
  ///
  /// @return     If the isolate successfully 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;

  bool LoadLoadingUnit(
      intptr_t loading_unit_id,
      std::unique_ptr<const fml::Mapping> snapshot_data,
      std::unique_ptr<const fml::Mapping> snapshot_instructions);

  void LoadLoadingUnitError(intptr_t loading_unit_id,
                            const std::string& error_message,
                            bool transient);

  DartIsolateGroupData& GetIsolateGroupData();

  const DartIsolateGroupData& GetIsolateGroupData() const;

 private:
  friend class IsolateConfiguration;
  class AutoFireClosure {
   public:
    explicit 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_;
  std::unordered_set<fml::RefPtr<DartSnapshot>> loading_unit_snapshots_;
  fml::RefPtr<fml::TaskRunner> message_handling_task_runner_;
  const bool may_insecurely_connect_to_all_domains_;
  std::string domain_network_policy_;

  static std::weak_ptr<DartIsolate> CreateRootIsolate(
      const Settings& settings,
      fml::RefPtr<const DartSnapshot> isolate_snapshot,
      std::unique_ptr<PlatformConfiguration> platform_configuration,
      const Flags& flags,
      const fml::closure& isolate_create_callback,
      const fml::closure& isolate_shutdown_callback,
      const UIDartState::Context& context,
      const DartIsolate* spawning_isolate = nullptr);

  DartIsolate(const Settings& settings,
              bool is_root_isolate,
              const UIDartState::Context& context);

  //----------------------------------------------------------------------------
  /// @brief      Initializes the given (current) isolate.
  ///
  /// @param[in]  dart_isolate  The current isolate that is to be initialized.
  ///
  /// @return     Whether the initialization succeeded. Irrespective of whether
  ///             the initialization suceeded, the current isolate will still be
  ///             active.
  ///
  [[nodiscard]] bool Initialize(Dart_Isolate dart_isolate);

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

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

  [[nodiscard]] bool LoadLibraries();

  bool UpdateThreadPoolNames() const;

  [[nodiscard]] bool MarkIsolateRunnable();

  void OnShutdownCallback();

  // |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);

  typedef std::function<Dart_Isolate(std::shared_ptr<DartIsolateGroupData>*,
                                     std::shared_ptr<DartIsolate>*,
                                     Dart_IsolateFlags*,
                                     char**)>
      IsolateMaker;

  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,
      const IsolateMaker& make_isolate);

  static bool InitializeIsolate(
      const 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);

  // |Dart_DeferredLoadHandler|
  static Dart_Handle OnDartLoadLibrary(intptr_t loading_unit_id);

  static void SpawnIsolateShutdownCallback(
      std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
      std::shared_ptr<DartIsolate>* isolate_data);

  FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate);
};

}  // namespace flutter

#endif  // FLUTTER_RUNTIME_DART_ISOLATE_H_
