// Copyright (c) 2016, 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_BIN_LOADER_H_
#define RUNTIME_BIN_LOADER_H_

#include "bin/isolate_data.h"
#include "bin/thread.h"
#include "include/dart_api.h"
#include "include/dart_native_api.h"
#include "platform/assert.h"
#include "platform/globals.h"

namespace dart {
namespace bin {

class Loader {
 public:
  explicit Loader(IsolateData* isolate_data);
  ~Loader();

  static void InitForSnapshot(const char* snapshot_uri);

  static Dart_Handle ReloadNativeExtensions();

  // Loads contents of the specified url.
  static Dart_Handle LoadUrlContents(Dart_Handle url,
                                     uint8_t** payload,
                                     intptr_t* payload_length);

  static void ResolveDependenciesAsFilePaths();

  // A static tag handler that hides all usage of a loader for an isolate.
  static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
                                       Dart_Handle library,
                                       Dart_Handle url);

  Dart_Handle error() const { return error_; }

  static void InitOnce();

 private:
  // The port assigned to our native message handler.
  Dart_Port port_;
  // Each Loader is associated with an Isolate via its IsolateData.
  IsolateData* isolate_data_;
  // Remember the first error that occurs during loading.
  Dart_Handle error_;
  // This monitor is used to protect the pending operations count and the
  // I/O result queue.
  Monitor* monitor_;

  // The number of operations dispatched to the service isolate for loading.
  // Must be accessed with monitor_ held.
  intptr_t pending_operations_;

  // The result of an I/O request to the service isolate. Payload is either
  // a UInt8Array or a C string containing an error message.
  struct IOResult {
    uint8_t* payload;
    intptr_t payload_length;
    char* library_uri;
    char* uri;
    char* resolved_uri;
    int8_t tag;

    void Setup(Dart_CObject* message);
    void Cleanup();
  };
  // An array of I/O results queued from the service isolate.
  IOResult* results_;
  intptr_t results_length_;
  intptr_t results_capacity_;
  uint8_t* payload_;
  intptr_t payload_length_;
  typedef bool (*ProcessResult)(Loader* loader, IOResult* result);

  intptr_t results_length() {
    return *static_cast<volatile intptr_t*>(&results_length_);
  }

  // Send the loader init request to the service isolate.
  void Init(const char* package_root,
            const char* packages_file,
            const char* working_directory,
            const char* root_script_uri);

  // Send a request for a dart-ext: import to the service isolate.
  void SendImportExtensionRequest(Dart_Handle url, Dart_Handle library_url);

  // Send a request from the tag handler to the service isolate.
  void SendRequest(intptr_t tag, Dart_Handle url, Dart_Handle library_url);

  static Dart_Handle SendAndProcessReply(intptr_t tag,
                                         Dart_Handle url,
                                         uint8_t** payload,
                                         intptr_t* payload_length);

  static Dart_Handle ResolveAsFilePath(Dart_Handle url,
                                       uint8_t** payload,
                                       intptr_t* payload_length);

  /// Queue |message| and notify the loader that a message is available.
  void QueueMessage(Dart_CObject* message);

  /// Blocks the caller until the loader is finished.
  void BlockUntilComplete(ProcessResult process_result);

  /// Saves a script dependency when applicable.
  static void AddDependencyLocked(Loader* loader, const char* resolved_uri);

  /// Returns false if |result| is an error and the loader should quit.
  static bool ProcessResultLocked(Loader* loader, IOResult* result);

  /// Returns false if |result| is an error and the loader should quit.
  static bool ProcessPayloadResultLocked(Loader* loader, IOResult* result);

  /// Returns false if an error occurred and the loader should quit.
  bool ProcessQueueLocked(ProcessResult process_result);

  // Special inner tag handler for dart: uris.
  static Dart_Handle DartColonLibraryTagHandler(Dart_LibraryTag tag,
                                                Dart_Handle library,
                                                Dart_Handle url,
                                                const char* library_url_string,
                                                const char* url_string);

  // We use one native message handler callback for N loaders. The native
  // message handler callback provides us with the Dart_Port which we use as a
  // key into our map of active loaders from |port| to |isolate_data|.

  // Static information to map Dart_Port back to the isolate in question.
  struct LoaderInfo {
    Dart_Port port;
    IsolateData* isolate_data;
  };

  // The map of active loaders.
  static Mutex* loader_infos_lock_;
  static LoaderInfo* loader_infos_;
  static intptr_t loader_infos_length_;
  static intptr_t loader_infos_capacity_;

  static void AddLoader(Dart_Port port, IsolateData* data);
  static void RemoveLoader(Dart_Port port);
  static intptr_t LoaderIndexFor(Dart_Port port);
  static Loader* LoaderFor(Dart_Port port);
  static Loader* LoaderForLocked(Dart_Port port);

  // This is the global callback for the native message handlers.
  static void NativeMessageHandler(Dart_Port dest_port_id,
                                   Dart_CObject* message);
};

}  // namespace bin
}  // namespace dart

#endif  // RUNTIME_BIN_LOADER_H_
