// 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_SERVICE_ISOLATE_H_
#define FLUTTER_RUNTIME_DART_SERVICE_ISOLATE_H_

#include <functional>
#include <mutex>
#include <set>
#include <string>

#include "flutter/fml/compiler_specific.h"
#include "third_party/dart/runtime/include/dart_api.h"

namespace flutter {

//------------------------------------------------------------------------------
/// @brief      Utility methods for interacting with the DartVM managed service
///             isolate present in debug and profile runtime modes.
///
class DartServiceIsolate {
 public:
  //----------------------------------------------------------------------------
  /// The handle used to refer to callbacks registered with the service isolate.
  ///
  using CallbackHandle = ptrdiff_t;

  //----------------------------------------------------------------------------
  /// A callback made by the Dart VM when the observatory is ready. The argument
  /// indicates the observatory URI.
  ///
  using ObservatoryServerStateCallback =
      std::function<void(const std::string& observatory_uri)>;

  //----------------------------------------------------------------------------
  /// @brief      Start the service isolate. This call may only be made in the
  ///             Dart VM initiated isolate creation callback. It is only valid
  ///             to make this call when the VM explicitly requests the creation
  ///             of the service isolate. The VM does this by specifying the
  ///             script URI to be `DART_VM_SERVICE_ISOLATE_NAME`. The isolate
  ///             to be designated as the service isolate must already be
  ///             created (but not running) when this call is made.
  ///
  /// @param[in]  server_ip                     The service protocol IP address.
  /// @param[in]  server_port                   The service protocol port.
  /// @param[in]  embedder_tag_handler          The library tag handler.
  /// @param[in]  disable_origin_check          If websocket origin checks must
  ///                                           be enabled.
  /// @param[in]  disable_service_auth_codes    If service auth codes must be
  ///                                           enabled.
  /// @param[in]  enable_service_port_fallback  If fallback to port 0 must be
  ///                                           enabled when the bind fails.
  /// @param      error                         The error when this method
  ///                                           returns false. This string must
  ///                                           be freed by the caller using
  ///                                           `free`.
  ///
  /// @return     If the startup was successful. Refer to the `error` for
  ///             details on failure.
  ///
  static bool Startup(const std::string& server_ip,
                      intptr_t server_port,
                      Dart_LibraryTagHandler embedder_tag_handler,
                      bool disable_origin_check,
                      bool disable_service_auth_codes,
                      bool enable_service_port_fallback,
                      char** error);

  //----------------------------------------------------------------------------
  /// @brief      Add a callback that will get invoked when the observatory
  ///             starts up. If the observatory has already started before this
  ///             call is made, the callback is invoked immediately.
  ///
  ///             This method is thread safe.
  ///
  /// @param[in]  callback  The callback with information about the observatory.
  ///
  /// @return     A handle for the callback that can be used later in
  ///             `RemoveServerStatusCallback`.
  ///
  [[nodiscard]] static CallbackHandle AddServerStatusCallback(
      const ObservatoryServerStateCallback& callback);

  //----------------------------------------------------------------------------
  /// @brief      Removed a callback previously registered via
  ///             `AddServiceStatusCallback`.
  ///
  ///             This method is thread safe.
  ///
  /// @param[in]  handle  The handle
  ///
  /// @return     If the callback was unregistered. This may fail if there was
  ///             no such callback with that handle.
  ///
  static bool RemoveServerStatusCallback(CallbackHandle handle);

 private:
  // Native entries.
  static void NotifyServerState(Dart_NativeArguments args);
  static void Shutdown(Dart_NativeArguments args);

  static std::mutex callbacks_mutex_;
  static std::set<std::unique_ptr<ObservatoryServerStateCallback>> callbacks_;
};

}  // namespace flutter

#endif  // FLUTTER_RUNTIME_DART_SERVICE_ISOLATE_H_
