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

#include "flutter/runtime/dart_service_isolate.h"

#include <string.h>

#include "dart/runtime/include/dart_api.h"
#include "flutter/runtime/embedder_resources.h"
#include "lib/ftl/logging.h"
#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_library_natives.h"
#include "lib/tonic/logging/dart_error.h"

#define RETURN_ERROR_HANDLE(handle) \
  if (Dart_IsError(handle)) {       \
    return handle;                  \
  }

#define SHUTDOWN_ON_ERROR(handle)           \
  if (Dart_IsError(handle)) {               \
    *error = strdup(Dart_GetError(handle)); \
    Dart_ExitScope();                       \
    Dart_ShutdownIsolate();                 \
    return false;                           \
  }

#define kLibrarySourceNamePrefix "/vmservice"
static const char* kServiceIsolateScript = "vmservice_io.dart";

namespace flutter {
namespace runtime {
extern ResourcesEntry __flutter_embedded_service_isolate_resources_[];
}
}

namespace blink {
namespace {

static Dart_LibraryTagHandler g_embedder_tag_handler;
static tonic::DartLibraryNatives* g_natives;
static EmbedderResources* g_resources;
static std::string observatory_uri_;

Dart_NativeFunction GetNativeFunction(Dart_Handle name,
                                      int argument_count,
                                      bool* auto_setup_scope) {
  FTL_CHECK(g_natives);
  return g_natives->GetNativeFunction(name, argument_count, auto_setup_scope);
}

const uint8_t* GetSymbol(Dart_NativeFunction native_function) {
  FTL_CHECK(g_natives);
  return g_natives->GetSymbol(native_function);
}

}  // namespace

void DartServiceIsolate::TriggerResourceLoad(Dart_NativeArguments args) {
  Dart_Handle library = Dart_RootLibrary();
  FTL_DCHECK(!Dart_IsError(library));
  Dart_Handle result = LoadResources(library);
  FTL_DCHECK(!Dart_IsError(result));
}

void DartServiceIsolate::NotifyServerState(Dart_NativeArguments args) {
  Dart_Handle exception = nullptr;
  std::string uri = tonic::DartConverter<std::string>::FromArguments(args, 0, exception);
  if (!exception) {
    observatory_uri_ = uri;
  }
}

std::string DartServiceIsolate::GetObservatoryUri() {
  return observatory_uri_;
}

void DartServiceIsolate::Shutdown(Dart_NativeArguments args) {
  // NO-OP.
}

bool DartServiceIsolate::Startup(std::string server_ip,
                                 intptr_t server_port,
                                 Dart_LibraryTagHandler embedder_tag_handler,
                                 bool running_precompiled,
                                 bool disable_origin_check,
                                 char** error) {
  Dart_Isolate isolate = Dart_CurrentIsolate();
  FTL_CHECK(isolate);

  // Remember the embedder's library tag handler.
  g_embedder_tag_handler = embedder_tag_handler;
  FTL_CHECK(g_embedder_tag_handler);

  // Setup native entries.
  if (!g_natives) {
    g_natives = new tonic::DartLibraryNatives();
    g_natives->Register({
        {"VMServiceIO_NotifyServerState", NotifyServerState, 1, true},
        {"VMServiceIO_Shutdown", Shutdown, 0, true},
    });
  }

  if (!g_resources) {
    g_resources = new EmbedderResources(
        &flutter::runtime::__flutter_embedded_service_isolate_resources_[0]);
  }

  Dart_Handle result;

  if (running_precompiled) {
    Dart_Handle uri = Dart_NewStringFromCString("dart:vmservice_sky");
    Dart_Handle library = Dart_LookupLibrary(uri);
    SHUTDOWN_ON_ERROR(library);
    result = Dart_SetRootLibrary(library);
    SHUTDOWN_ON_ERROR(result);
    result = Dart_SetNativeResolver(library, GetNativeFunction, GetSymbol);
    SHUTDOWN_ON_ERROR(result);
  } else {
    // Use our own library tag handler when loading service isolate sources.
    Dart_SetLibraryTagHandler(DartServiceIsolate::LibraryTagHandler);
    // Load main script.
    Dart_Handle library = LoadScript(kServiceIsolateScript);
    FTL_DCHECK(library != Dart_Null());
    SHUTDOWN_ON_ERROR(library);
    // Setup native entry resolution.
    result = Dart_SetNativeResolver(library, GetNativeFunction, GetSymbol);

    SHUTDOWN_ON_ERROR(result);
    // Finalize loading.
    result = Dart_FinalizeLoading(false);
    SHUTDOWN_ON_ERROR(result);
  }

  // Make runnable.
  Dart_ExitScope();
  Dart_ExitIsolate();
  bool retval = Dart_IsolateMakeRunnable(isolate);
  if (!retval) {
    Dart_EnterIsolate(isolate);
    Dart_ShutdownIsolate();
    *error = strdup("Invalid isolate state - Unable to make it runnable.");
    return false;
  }
  Dart_EnterIsolate(isolate);
  Dart_EnterScope();

  Dart_Handle library = Dart_RootLibrary();
  SHUTDOWN_ON_ERROR(library);

  // Set the HTTP server's ip.
  result = Dart_SetField(library, Dart_NewStringFromCString("_ip"),
                         Dart_NewStringFromCString(server_ip.c_str()));
  SHUTDOWN_ON_ERROR(result);
  // If we have a port specified, start the server immediately.
  bool auto_start = server_port >= 0;
  if (server_port < 0) {
    // Adjust server_port to port 0 which will result in the first available
    // port when the HTTP server is started.
    server_port = 0;
  }
  // Set the HTTP's servers port.
  result = Dart_SetField(library, Dart_NewStringFromCString("_port"),
                         Dart_NewInteger(server_port));
  SHUTDOWN_ON_ERROR(result);
  result = Dart_SetField(library, Dart_NewStringFromCString("_autoStart"),
                         Dart_NewBoolean(auto_start));
  SHUTDOWN_ON_ERROR(result);
  result =
      Dart_SetField(library, Dart_NewStringFromCString("_originCheckDisabled"),
                    Dart_NewBoolean(disable_origin_check));
  SHUTDOWN_ON_ERROR(result);
  return true;
}

Dart_Handle DartServiceIsolate::GetSource(const char* name) {
  const intptr_t kBufferSize = 512;
  char buffer[kBufferSize];
  snprintf(&buffer[0], kBufferSize - 1, "%s/%s", kLibrarySourceNamePrefix,
           name);
  const char* vmservice_source = NULL;
  int r = g_resources->ResourceLookup(buffer, &vmservice_source);
  FTL_DCHECK(r != EmbedderResources::kNoSuchInstance);
  return Dart_NewStringFromCString(vmservice_source);
}

Dart_Handle DartServiceIsolate::LoadScript(const char* name) {
  Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_sky");
  Dart_Handle source = GetSource(name);
  return Dart_LoadScript(url, Dart_Null(), source, 0, 0);
}

Dart_Handle DartServiceIsolate::LoadSource(Dart_Handle library,
                                           const char* name) {
  Dart_Handle url = Dart_NewStringFromCString(name);
  Dart_Handle source = GetSource(name);
  return Dart_LoadSource(library, url, Dart_Null(), source, 0, 0);
}

Dart_Handle DartServiceIsolate::LoadResource(Dart_Handle library,
                                             const char* resource_name) {
  // Prepare for invoke call.
  Dart_Handle name = Dart_NewStringFromCString(resource_name);
  RETURN_ERROR_HANDLE(name);
  const char* data_buffer = NULL;
  int data_buffer_length =
      g_resources->ResourceLookup(resource_name, &data_buffer);
  FTL_DCHECK(data_buffer_length != EmbedderResources::kNoSuchInstance);
  Dart_Handle data_list =
      Dart_NewTypedData(Dart_TypedData_kUint8, data_buffer_length);
  RETURN_ERROR_HANDLE(data_list);
  Dart_TypedData_Type type = Dart_TypedData_kInvalid;
  void* data_list_buffer = NULL;
  intptr_t data_list_buffer_length = 0;
  Dart_Handle result = Dart_TypedDataAcquireData(
      data_list, &type, &data_list_buffer, &data_list_buffer_length);
  RETURN_ERROR_HANDLE(result);
  FTL_DCHECK(data_buffer_length == data_list_buffer_length);
  FTL_DCHECK(data_list_buffer != NULL);
  FTL_DCHECK(type = Dart_TypedData_kUint8);
  memmove(data_list_buffer, &data_buffer[0], data_buffer_length);
  result = Dart_TypedDataReleaseData(data_list);
  RETURN_ERROR_HANDLE(result);

  // Make invoke call.
  const intptr_t kNumArgs = 2;
  Dart_Handle args[kNumArgs] = {name, data_list};
  result = Dart_Invoke(library, Dart_NewStringFromCString("_addResource"),
                       kNumArgs, args);
  return result;
}

Dart_Handle DartServiceIsolate::LoadResources(Dart_Handle library) {
  Dart_Handle result = Dart_Null();
  intptr_t prefixLen = strlen(kLibrarySourceNamePrefix);
  for (intptr_t i = 0; g_resources->Path(i) != NULL; i++) {
    const char* path = g_resources->Path(i);
    // If it doesn't begin with kLibrarySourceNamePrefix it is a frontend
    // resource.
    if (strncmp(path, kLibrarySourceNamePrefix, prefixLen) != 0) {
      result = LoadResource(library, path);
      if (Dart_IsError(result)) {
        break;
      }
    }
  }
  return result;
}

Dart_Handle DartServiceIsolate::LibraryTagHandler(Dart_LibraryTag tag,
                                                  Dart_Handle library,
                                                  Dart_Handle url) {
  if (!Dart_IsLibrary(library)) {
    return Dart_NewApiError("not a library");
  }
  if (!Dart_IsString(url)) {
    return Dart_NewApiError("url is not a string");
  }
  const char* url_string = NULL;
  Dart_Handle result = Dart_StringToCString(url, &url_string);
  if (Dart_IsError(result)) {
    return result;
  }
  Dart_Handle library_url = Dart_LibraryUrl(library);
  const char* library_url_string = NULL;
  result = Dart_StringToCString(library_url, &library_url_string);
  if (Dart_IsError(result)) {
    return result;
  }
  if (tag == Dart_kImportTag) {
    // Embedder handles all requests for external libraries.
    return g_embedder_tag_handler(tag, library, url);
  }
  FTL_DCHECK((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
  if (tag == Dart_kCanonicalizeUrl) {
    // url is already canonicalized.
    return url;
  }
  // Get source from builtin resources.
  Dart_Handle source = GetSource(url_string);
  if (Dart_IsError(source)) {
    return source;
  }
  return Dart_LoadSource(library, url, Dart_Null(), source, 0, 0);
}

}  // namespace blink
