// Copyright (c) 2013, 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.

#include "bin/vmservice_impl.h"

#include "include/dart_api.h"

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/isolate_data.h"
#include "bin/platform.h"
#include "bin/thread.h"
#include "bin/utils.h"
#include "platform/text_buffer.h"

namespace dart {
namespace bin {

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

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

#define kLibrarySourceNamePrefix "/vmservice"
static const char* const kVMServiceIOLibraryUri = "dart:vmservice_io";
static const char* const kVMServiceIOLibraryScriptResourceName =
    "vmservice_io.dart";

struct ResourcesEntry {
  const char* path_;
  const char* resource_;
  int length_;
};

extern ResourcesEntry __service_bin_resources_[];

class Resources {
 public:
  static const int kNoSuchInstance = -1;
  static int ResourceLookup(const char* path, const char** resource) {
    ResourcesEntry* table = ResourcesTable();
    for (int i = 0; table[i].path_ != NULL; i++) {
      const ResourcesEntry& entry = table[i];
      if (strcmp(path, entry.path_) == 0) {
        *resource = entry.resource_;
        ASSERT(entry.length_ > 0);
        return entry.length_;
      }
    }
    return kNoSuchInstance;
  }

  static const char* Path(int idx) {
    ASSERT(idx >= 0);
    ResourcesEntry* entry = At(idx);
    if (entry == NULL) {
      return NULL;
    }
    ASSERT(entry->path_ != NULL);
    return entry->path_;
  }

 private:
  static ResourcesEntry* At(int idx) {
    ASSERT(idx >= 0);
    ResourcesEntry* table = ResourcesTable();
    for (int i = 0; table[i].path_ != NULL; i++) {
      if (idx == i) {
        return &table[i];
      }
    }
    return NULL;
  }
  static ResourcesEntry* ResourcesTable() {
    return &__service_bin_resources_[0];
  }

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
};


void NotifyServerState(Dart_NativeArguments args) {
  Dart_EnterScope();
  const char* ip_chars;
  Dart_Handle ip_arg = Dart_GetNativeArgument(args, 0);
  if (Dart_IsError(ip_arg)) {
    VmService::SetServerIPAndPort("", 0);
    Dart_ExitScope();
    return;
  }
  Dart_Handle result = Dart_StringToCString(ip_arg, &ip_chars);
  if (Dart_IsError(result)) {
    VmService::SetServerIPAndPort("", 0);
    Dart_ExitScope();
    return;
  }
  Dart_Handle port_arg = Dart_GetNativeArgument(args, 1);
  if (Dart_IsError(port_arg)) {
    VmService::SetServerIPAndPort("", 0);
    Dart_ExitScope();
    return;
  }
  int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
  VmService::SetServerIPAndPort(ip_chars, port);
  Dart_ExitScope();
}


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

struct VmServiceIONativeEntry {
  const char* name;
  int num_arguments;
  Dart_NativeFunction function;
};


static VmServiceIONativeEntry _VmServiceIONativeEntries[] = {
  {"VMServiceIO_NotifyServerState", 2, NotifyServerState},
  {"VMServiceIO_Shutdown", 0, Shutdown },
};


static Dart_NativeFunction VmServiceIONativeResolver(Dart_Handle name,
                                                     int num_arguments,
                                                     bool* auto_setup_scope) {
  const char* function_name = NULL;
  Dart_Handle result = Dart_StringToCString(name, &function_name);
  ASSERT(!Dart_IsError(result));
  ASSERT(function_name != NULL);
  *auto_setup_scope = true;
  intptr_t n =
      sizeof(_VmServiceIONativeEntries) / sizeof(_VmServiceIONativeEntries[0]);
  for (intptr_t i = 0; i < n; i++) {
    VmServiceIONativeEntry entry = _VmServiceIONativeEntries[i];
    if ((strcmp(function_name, entry.name) == 0) &&
        (num_arguments == entry.num_arguments)) {
      return entry.function;
    }
  }
  return NULL;
}


const char* VmService::error_msg_ = NULL;
char VmService::server_ip_[kServerIpStringBufferSize];
intptr_t VmService::server_port_ = 0;


bool VmService::LoadForGenPrecompiled() {
  Dart_Handle result;
  Dart_SetLibraryTagHandler(LibraryTagHandler);
  Dart_Handle library = LoadLibrary(kVMServiceIOLibraryScriptResourceName);
  ASSERT(library != Dart_Null());
  SHUTDOWN_ON_ERROR(library);
  result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
  SHUTDOWN_ON_ERROR(result);
  result = Dart_FinalizeLoading(false);
  SHUTDOWN_ON_ERROR(result);
  return true;
}


bool VmService::Setup(const char* server_ip,
                      intptr_t server_port,
                      bool running_precompiled) {
  Dart_Isolate isolate = Dart_CurrentIsolate();
  ASSERT(isolate != NULL);
  SetServerIPAndPort("", 0);

  Dart_Handle result;

  // Prepare builtin and its dependent libraries for use to resolve URIs.
  // Set up various closures, e.g: printing, timers etc.
  // Set up 'package root' for URI resolution.
  result = DartUtils::PrepareForScriptLoading(true, false);
  SHUTDOWN_ON_ERROR(result);

  if (running_precompiled) {
    Dart_Handle url = DartUtils::NewString(kVMServiceIOLibraryUri);
    Dart_Handle library = Dart_LookupLibrary(url);
    SHUTDOWN_ON_ERROR(library);
    result = Dart_SetRootLibrary(library);
    SHUTDOWN_ON_ERROR(library);
    result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
    SHUTDOWN_ON_ERROR(result);
  } else {
    // Load main script.
    Dart_SetLibraryTagHandler(LibraryTagHandler);
    Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
    ASSERT(library != Dart_Null());
    SHUTDOWN_ON_ERROR(library);
    result = Dart_SetNativeResolver(library, VmServiceIONativeResolver, NULL);
    SHUTDOWN_ON_ERROR(result);
    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_msg_ = "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 HTTP server state.
  result = DartUtils::SetStringField(library, "_ip", server_ip);
  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;
  }
  result = DartUtils::SetIntegerField(library, "_port", server_port);
  SHUTDOWN_ON_ERROR(result);
  result = Dart_SetField(library,
                         DartUtils::NewString("_autoStart"),
                         Dart_NewBoolean(auto_start));
  SHUTDOWN_ON_ERROR(result);

  // Are we running on Windows?
#if defined(TARGET_OS_WINDOWS)
  Dart_Handle is_windows = Dart_True();
#else
  Dart_Handle is_windows = Dart_False();
#endif
  result =
      Dart_SetField(library, DartUtils::NewString("_isWindows"), is_windows);
  SHUTDOWN_ON_ERROR(result);

  // Get _getWatchSignalInternal from dart:io.
  Dart_Handle dart_io_str = Dart_NewStringFromCString(DartUtils::kIOLibURL);
  SHUTDOWN_ON_ERROR(dart_io_str);
  Dart_Handle io_lib = Dart_LookupLibrary(dart_io_str);
  SHUTDOWN_ON_ERROR(io_lib);
  Dart_Handle function_name =
      Dart_NewStringFromCString("_getWatchSignalInternal");
  SHUTDOWN_ON_ERROR(function_name);
  Dart_Handle signal_watch = Dart_Invoke(io_lib, function_name, 0, NULL);
  SHUTDOWN_ON_ERROR(signal_watch);
  Dart_Handle field_name = Dart_NewStringFromCString("_signalWatch");
  SHUTDOWN_ON_ERROR(field_name);
  result =
      Dart_SetField(library, field_name, signal_watch);
  SHUTDOWN_ON_ERROR(field_name);
  return true;
}


const char* VmService::GetErrorMessage() {
  return error_msg_ == NULL ? "No error." : error_msg_;
}


void VmService::SetServerIPAndPort(const char* ip, intptr_t port) {
  if (ip == NULL) {
    ip = "";
  }
  strncpy(server_ip_, ip, kServerIpStringBufferSize);
  server_ip_[kServerIpStringBufferSize - 1] = '\0';
  server_port_ = port;
}


Dart_Handle VmService::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 = Resources::ResourceLookup(buffer, &vmservice_source);
  if (r == Resources::kNoSuchInstance) {
    FATAL1("vm-service: Could not find embedded source file: %s ", buffer);
  }
  ASSERT(r != Resources::kNoSuchInstance);
  return Dart_NewStringFromCString(vmservice_source);
}


Dart_Handle VmService::LoadScript(const char* name) {
  Dart_Handle uri = Dart_NewStringFromCString(kVMServiceIOLibraryUri);
  Dart_Handle source = GetSource(name);
  return Dart_LoadScript(uri, source, 0, 0);
}


Dart_Handle VmService::LoadLibrary(const char* name) {
  Dart_Handle uri = Dart_NewStringFromCString(kVMServiceIOLibraryUri);
  Dart_Handle source = GetSource(name);
  return Dart_LoadLibrary(uri, source, 0, 0);
}


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


Dart_Handle VmService::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 DartUtils::LibraryTagHandler(tag, library, url);
  }
  ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
  if (tag == Dart_kCanonicalizeUrl) {
    // url is already canonicalized.
    return url;
  }
  Dart_Handle source = GetSource(url_string);
  if (Dart_IsError(source)) {
    return source;
  }
  return Dart_LoadSource(library, url, source, 0, 0);
}


}  // namespace bin
}  // namespace dart
