// Copyright (c) 2012, 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/dartutils.h"

#include "include/dart_api.h"
#include "include/dart_native_api.h"

#include "platform/assert.h"
#include "platform/globals.h"

#include "bin/extensions.h"
#include "bin/directory.h"
#include "bin/file.h"
#include "bin/io_buffer.h"
#include "bin/utils.h"
#include "bin/socket.h"

namespace dart {
namespace bin {

const char* DartUtils::original_working_directory = NULL;
const char* DartUtils::kDartScheme = "dart:";
const char* DartUtils::kDartExtensionScheme = "dart-ext:";
const char* DartUtils::kAsyncLibURL = "dart:async";
const char* DartUtils::kBuiltinLibURL = "dart:builtin";
const char* DartUtils::kCoreLibURL = "dart:core";
const char* DartUtils::kIOLibURL = "dart:io";
const char* DartUtils::kIOLibPatchURL = "dart:io-patch";
const char* DartUtils::kUriLibURL = "dart:uri";
const char* DartUtils::kHttpScheme = "http:";

const char* DartUtils::kIdFieldName = "_id";

uint8_t DartUtils::magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc };

static bool IsWindowsHost() {
#if defined(TARGET_OS_WINDOWS)
  return true;
#else  // defined(TARGET_OS_WINDOWS)
  return false;
#endif  // defined(TARGET_OS_WINDOWS)
}


static Dart_Handle SingleArgDart_Invoke(Dart_Handle arg, Dart_Handle lib,
                                        const char* method) {
  const int kNumArgs = 1;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = arg;
  return Dart_Invoke(lib, DartUtils::NewString(method), kNumArgs, dart_args);
}


const char* DartUtils::MapLibraryUrl(CommandLineOptions* url_mapping,
                                     const char* url_string) {
  ASSERT(url_mapping != NULL);
  // We need to check if the passed in url is found in the url_mapping array,
  // in that case use the mapped entry.
  int len = strlen(url_string);
  for (int idx = 0; idx < url_mapping->count(); idx++) {
    const char* url_name = url_mapping->GetArgument(idx);
    if (!strncmp(url_string, url_name, len) && (url_name[len] == ',')) {
      const char* url_mapped_name = url_name + len + 1;
      if (strlen(url_mapped_name) != 0) {
        return url_mapped_name;  // Found a mapping for this URL.
      }
    }
  }
  return NULL;  // Did not find a mapping for this URL.
}


int64_t DartUtils::GetIntegerValue(Dart_Handle value_obj) {
  ASSERT(Dart_IsInteger(value_obj));
  int64_t value = 0;
  Dart_Handle result = Dart_IntegerToInt64(value_obj, &value);
  ASSERT(!Dart_IsError(result));
  return value;
}


intptr_t DartUtils::GetIntptrValue(Dart_Handle value_obj) {
  ASSERT(Dart_IsInteger(value_obj));
  int64_t value = 0;
  Dart_Handle result = Dart_IntegerToInt64(value_obj, &value);
  ASSERT(!Dart_IsError(result));
  return static_cast<intptr_t>(value);
}


bool DartUtils::GetInt64Value(Dart_Handle value_obj, int64_t* value) {
  bool valid = Dart_IsInteger(value_obj);
  if (valid) {
    Dart_Handle result = Dart_IntegerFitsIntoInt64(value_obj, &valid);
    ASSERT(!Dart_IsError(result));
  }
  if (!valid) return false;
  Dart_Handle result = Dart_IntegerToInt64(value_obj, value);
  ASSERT(!Dart_IsError(result));
  return true;
}


const char* DartUtils::GetStringValue(Dart_Handle str_obj) {
  const char* cstring = NULL;
  Dart_Handle result = Dart_StringToCString(str_obj, &cstring);
  ASSERT(!Dart_IsError(result));
  return cstring;
}


bool DartUtils::GetBooleanValue(Dart_Handle bool_obj) {
  bool value = false;
  Dart_Handle result = Dart_BooleanValue(bool_obj, &value);
  ASSERT(!Dart_IsError(result));
  return value;
}


void DartUtils::SetIntegerField(Dart_Handle handle,
                                const char* name,
                                intptr_t val) {
  Dart_Handle result = Dart_SetField(handle,
                                     NewString(name),
                                     Dart_NewInteger(val));
  ASSERT(!Dart_IsError(result));
}


intptr_t DartUtils::GetIntegerField(Dart_Handle handle,
                                    const char* name) {
  Dart_Handle result = Dart_GetField(handle, NewString(name));
  ASSERT(!Dart_IsError(result));
  intptr_t value = DartUtils::GetIntegerValue(result);
  return value;
}


void DartUtils::SetStringField(Dart_Handle handle,
                               const char* name,
                               const char* val) {
  Dart_Handle result = Dart_SetField(handle, NewString(name), NewString(val));
  ASSERT(!Dart_IsError(result));
}


bool DartUtils::IsDartSchemeURL(const char* url_name) {
  static const intptr_t kDartSchemeLen = strlen(kDartScheme);
  // If the URL starts with "dart:" then it is considered as a special
  // library URL which is handled differently from other URLs.
  return (strncmp(url_name, kDartScheme, kDartSchemeLen) == 0);
}


bool DartUtils::IsHttpSchemeURL(const char* url_name) {
  static const intptr_t kHttpSchemeLen = strlen(kHttpScheme);
  return (strncmp(url_name, kHttpScheme, kHttpSchemeLen) == 0);
}


bool DartUtils::IsDartExtensionSchemeURL(const char* url_name) {
  static const intptr_t kDartExtensionSchemeLen = strlen(kDartExtensionScheme);
  // If the URL starts with "dartext:" then it is considered as a special
  // extension library URL which is handled differently from other URLs.
  return
      (strncmp(url_name, kDartExtensionScheme, kDartExtensionSchemeLen) == 0);
}


bool DartUtils::IsDartIOLibURL(const char* url_name) {
  return (strcmp(url_name, kIOLibURL) == 0);
}


bool DartUtils::IsDartBuiltinLibURL(const char* url_name) {
  return (strcmp(url_name, kBuiltinLibURL) == 0);
}


Dart_Handle DartUtils::CanonicalizeURL(CommandLineOptions* url_mapping,
                                       Dart_Handle library,
                                       const char* url_str) {
  // Get the url of the including library.
  Dart_Handle library_url = Dart_LibraryUrl(library);
  if (Dart_IsError(library_url)) {
    return Dart_Error("accessing library url failed");
  }
  if (!Dart_IsString(library_url)) {
    return Dart_Error("library url is not a string");
  }
  const char* library_url_str = NULL;
  Dart_Handle result = Dart_StringToCString(library_url, &library_url_str);
  if (Dart_IsError(result)) {
    return Dart_Error("accessing library url characters failed");
  }
  if (url_mapping != NULL) {
    const char* mapped_library_url_str = MapLibraryUrl(url_mapping,
                                                       library_url_str);
    if (mapped_library_url_str != NULL) {
      library_url_str = mapped_library_url_str;
    }
  }
  // Calculate the canonical path.
  const char* canon_url_str = GetCanonicalPath(library_url_str, url_str);
  Dart_Handle canon_url = NewString(canon_url_str);
  free(const_cast<char*>(canon_url_str));

  return canon_url;
}


void* DartUtils::OpenFile(const char* name, bool write) {
  File* file = File::Open(name, write ? File::kWriteTruncate : File::kRead);
  return reinterpret_cast<void*>(file);
}


void DartUtils::ReadFile(const uint8_t** data,
                         intptr_t* file_len,
                         void* stream) {
  ASSERT(data != NULL);
  ASSERT(file_len != NULL);
  ASSERT(stream != NULL);
  File* file_stream = reinterpret_cast<File*>(stream);
  *file_len = file_stream->Length();
  ASSERT(*file_len > 0);
  uint8_t* text_buffer = reinterpret_cast<uint8_t*>(malloc(*file_len));
  ASSERT(text_buffer != NULL);
  if (!file_stream->ReadFully(text_buffer, *file_len)) {
    *data = NULL;
    *file_len = -1;  // Indicates read was not successful.
    return;
  }
  *data = text_buffer;
}


void DartUtils::WriteFile(const void* buffer,
                          intptr_t num_bytes,
                          void* stream) {
  ASSERT(stream != NULL);
  File* file_stream = reinterpret_cast<File*>(stream);
  bool bytes_written = file_stream->WriteFully(buffer, num_bytes);
  ASSERT(bytes_written);
}


void DartUtils::CloseFile(void* stream) {
  delete reinterpret_cast<File*>(stream);
}


// Writes string into socket.
// Return < 0 indicates an error.
// Return >= 0 number of bytes written.
static intptr_t SocketWriteString(intptr_t socket, const char* str,
                                  intptr_t len) {
    int r;
    intptr_t cursor = 0;
    do {
      r = Socket::Write(socket, &str[cursor], len);
      if (r < 0) {
        return r;
      }
      cursor += r;
      len -= r;
    } while (len > 0);
    ASSERT(len == 0);
    return cursor;
}


static uint8_t* SocketReadUntilEOF(intptr_t socket, intptr_t* response_len) {
  const intptr_t kInitialBufferSize = 16 * KB;
  intptr_t buffer_size = kInitialBufferSize;
  uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(buffer_size));
  ASSERT(buffer != NULL);
  intptr_t buffer_cursor = 0;
  do {
    int bytes_read = Socket::Read(socket, &buffer[buffer_cursor],
                                      buffer_size - buffer_cursor - 1);
    if (bytes_read < 0) {
      free(buffer);
      return NULL;
    }

    buffer_cursor += bytes_read;

    if (bytes_read == 0) {
      *response_len = buffer_cursor;
      buffer[buffer_cursor] = '\0';
      break;
    }

    // There is still more data to be read, check that we have room in the
    // buffer for more data.
    if (buffer_cursor == buffer_size - 1) {
      // Buffer is full. Increase buffer size.
      buffer_size *= 2;
      buffer = reinterpret_cast<uint8_t*>(realloc(buffer, buffer_size));
      ASSERT(buffer != NULL);
    }
  } while (true);
  return buffer;
}


static bool HttpGetRequestOkay(const char* response) {
  static const char* kOkayReply = "HTTP/1.0 200 OK";
  static const intptr_t kOkayReplyLen = strlen(kOkayReply);
  return (strncmp(response, kOkayReply, kOkayReplyLen) == 0);
}


static const uint8_t* HttpRequestGetPayload(const char* response) {
  const char* split = strstr(response, "\r\n\r\n");
  if (split != NULL) {
    return reinterpret_cast<const uint8_t*>(split+4);
  }
  return NULL;
}


// TODO(iposva): Allocate from the zone instead of leaking error string
// here. On the other hand the binary is about the exit anyway.
#define SET_ERROR_MSG(error_msg, format, ...)                                  \
  intptr_t len = snprintf(NULL, 0, format, __VA_ARGS__);                       \
  char *msg = reinterpret_cast<char*>(malloc(len + 1));                        \
  snprintf(msg, len + 1, format, __VA_ARGS__);                                 \
  *error_msg = msg


static const uint8_t* HttpGetRequest(const char* host, const char* path,
                                     int port, intptr_t* response_len,
                                     const char** error_msg) {
  OSError* error = NULL;
  SocketAddresses* addresses = Socket::LookupAddress(host, -1, &error);
  if (addresses == NULL || addresses->count() == 0) {
    SET_ERROR_MSG(error_msg, "Unable to resolve %s", host);
    return NULL;
  }

  int preferred_address = 0;
  for (int i = 0; i < addresses->count(); i++) {
    SocketAddress* address = addresses->GetAt(i);
    if (address->GetType() == SocketAddress::ADDRESS_LOOPBACK_IP_V4) {
      // Prefer the IP_V4 loop back.
      preferred_address = i;
      break;
    }
  }

  RawAddr addr = addresses->GetAt(preferred_address)->addr();
  intptr_t tcp_client = Socket::Create(addr);
  if (tcp_client < 0) {
    SET_ERROR_MSG(error_msg, "Unable to create socket to %s:%d", host, port);
    return NULL;
  }
  Socket::Connect(tcp_client, addr, port);
  if (tcp_client < 0) {
    SET_ERROR_MSG(error_msg, "Unable to connect to %s:%d", host, port);
    return NULL;
  }
  // Send get request.
  {
    const char* format =
        "GET %s HTTP/1.0\r\nUser-Agent: Dart VM\r\nHost: %s\r\n\r\n";
    intptr_t len = snprintf(NULL, 0, format, path, host);
    char* get_request = reinterpret_cast<char*>(malloc(len + 1));
    snprintf(get_request, len + 1, format, path, host);
    intptr_t r = SocketWriteString(tcp_client, get_request, len);
    free(get_request);
    if (r < len) {
      SET_ERROR_MSG(error_msg, "Unable to write to %s:%d - %d", host, port,
                    static_cast<int>(r));
      Socket::Close(tcp_client);
      return NULL;
    }
    ASSERT(r == len);
  }
  // Consume response.
  uint8_t* response = SocketReadUntilEOF(tcp_client, response_len);
  // Close socket.
  Socket::Close(tcp_client);
  if (response == NULL) {
    SET_ERROR_MSG(error_msg, "Unable to read from %s:%d", host, port);
    return NULL;
  }
  if (HttpGetRequestOkay(reinterpret_cast<const char*>(response)) == false) {
    SET_ERROR_MSG(error_msg, "Invalid HTTP response from %s:%d", host, port);
    free(response);
    return NULL;
  }
  return response;
}


static Dart_Handle ParseHttpUri(Dart_Handle uri, const char** host_str,
                                int64_t* port_int, const char** path_str) {
  ASSERT(host_str != NULL);
  ASSERT(port_int != NULL);
  ASSERT(path_str != NULL);
  Dart_Handle result;
  Dart_Handle builtin_lib =
      Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
  Dart_Handle path = DartUtils::PathFromUri(uri, builtin_lib);
  if (Dart_IsError(path)) {
    return path;
  }
  Dart_Handle host = DartUtils::HostFromUri(uri, builtin_lib);
  if (Dart_IsError(host)) {
    return host;
  }
  Dart_Handle port = DartUtils::PortFromUri(uri, builtin_lib);
  if (Dart_IsError(port)) {
    return port;
  }
  result = Dart_StringToCString(path, path_str);
  if (Dart_IsError(result)) {
    return result;
  }
  result = Dart_StringToCString(host, host_str);
  if (Dart_IsError(result)) {
    return result;
  }
  if (DartUtils::GetInt64Value(port, port_int) == false) {
    return Dart_Error("Invalid port");
  }
  return result;
}


Dart_Handle DartUtils::ReadStringFromHttp(const char* filename) {
  Dart_Handle uri = NewString(filename);
  if (Dart_IsError(uri)) {
    return uri;
  }
  const char* host_str = NULL;
  int64_t port_int = 0;
  const char* path_str = NULL;
  Dart_Handle result = ParseHttpUri(uri, &host_str, &port_int,
                                    &path_str);
  if (Dart_IsError(result)) {
    return result;
  }
  const char* error_msg = NULL;
  intptr_t len;
  const uint8_t* text_buffer = HttpGetRequest(host_str, path_str, port_int,
                                              &len, &error_msg);
  if (text_buffer == NULL) {
    return Dart_Error(error_msg);
  }
  const uint8_t* payload = HttpRequestGetPayload(
      reinterpret_cast<const char*>(text_buffer));
  if (payload == NULL) {
    return Dart_Error("Invalid HTTP response.");
  }
  // Subtract HTTP response from length.
  len -= (payload-text_buffer);
  ASSERT(len >= 0);
  Dart_Handle str = Dart_NewStringFromUTF8(payload, len);
  return str;
}


static const uint8_t* ReadFileFully(const char* filename,
                                    intptr_t* file_len,
                                    const char** error_msg) {
  void* stream = DartUtils::OpenFile(filename, false);
  if (stream == NULL) {
    SET_ERROR_MSG(error_msg, "Unable to open file: %s", filename);
    return NULL;
  }
  *file_len = -1;
  const uint8_t* text_buffer = NULL;
  DartUtils::ReadFile(&text_buffer, file_len, stream);
  if (text_buffer == NULL || *file_len == -1) {
    *error_msg = "Unable to read file contents";
    text_buffer = NULL;
  }
  DartUtils::CloseFile(stream);
  return text_buffer;
}


Dart_Handle DartUtils::ReadStringFromFile(const char* filename) {
  const char* error_msg = NULL;
  intptr_t len;
  const uint8_t* text_buffer = ReadFileFully(filename, &len, &error_msg);
  if (text_buffer == NULL) {
    return Dart_Error(error_msg);
  }
  Dart_Handle str = Dart_NewStringFromUTF8(text_buffer, len);
  return str;
}


Dart_Handle DartUtils::SetWorkingDirectory(Dart_Handle builtin_lib) {
  Dart_Handle directory = NewString(original_working_directory);
  return SingleArgDart_Invoke(directory, builtin_lib, "_setWorkingDirectory");
}


Dart_Handle DartUtils::ResolveScriptUri(Dart_Handle script_uri,
                                        Dart_Handle builtin_lib) {
  return SingleArgDart_Invoke(script_uri, builtin_lib, "_resolveScriptUri");
}


Dart_Handle DartUtils::FilePathFromUri(Dart_Handle script_uri,
                                       Dart_Handle builtin_lib) {
  return SingleArgDart_Invoke(script_uri, builtin_lib, "_filePathFromUri");
}


Dart_Handle DartUtils::PathFromUri(Dart_Handle script_uri,
                                   Dart_Handle builtin_lib) {
  return SingleArgDart_Invoke(script_uri, builtin_lib, "_pathFromHttpUri");
}


Dart_Handle DartUtils::HostFromUri(Dart_Handle script_uri,
                                     Dart_Handle builtin_lib) {
  return SingleArgDart_Invoke(script_uri, builtin_lib, "_hostFromHttpUri");
}


Dart_Handle DartUtils::PortFromUri(Dart_Handle script_uri,
                                   Dart_Handle builtin_lib) {
  return SingleArgDart_Invoke(script_uri, builtin_lib, "_portFromHttpUri");
}


Dart_Handle DartUtils::ResolveUri(Dart_Handle library_url,
                                  Dart_Handle url,
                                  Dart_Handle builtin_lib) {
  const int kNumArgs = 2;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = library_url;
  dart_args[1] = url;
  return Dart_Invoke(
      builtin_lib, NewString("_resolveUri"), kNumArgs, dart_args);
}


Dart_Handle DartUtils::LibraryTagHandler(Dart_LibraryTag tag,
                                         Dart_Handle library,
                                         Dart_Handle url) {
  if (!Dart_IsLibrary(library)) {
    return Dart_Error("not a library");
  }
  if (!Dart_IsString(url)) {
    return Dart_Error("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;
  }

  bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_string);
  bool is_io_library = DartUtils::IsDartIOLibURL(library_url_string);
  bool is_dart_extension_url = DartUtils::IsDartExtensionSchemeURL(url_string);

  // Handle URI canonicalization requests.
  if (tag == Dart_kCanonicalizeUrl) {
    // If this is a Dart Scheme URL or 'part' of a io library
    // then it is not modified as it will be handled internally.
    if (is_dart_scheme_url || is_io_library) {
      return url;
    }
    // Resolve the url within the context of the library's URL.
    Dart_Handle builtin_lib =
        Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
    Dart_Handle library_url = Dart_LibraryUrl(library);
    if (Dart_IsError(library_url)) {
      return library_url;
    }
    return ResolveUri(library_url, url, builtin_lib);
  }

  // Handle 'import' of dart scheme URIs (i.e they start with 'dart:').
  if (is_dart_scheme_url) {
    if (tag == Dart_kImportTag) {
      // Handle imports of other built-in libraries present in the SDK.
      if (DartUtils::IsDartIOLibURL(url_string)) {
        return Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
      }
      return Dart_Error("Do not know how to load '%s'", url_string);
    } else {
      ASSERT(tag == Dart_kSourceTag);
      return Dart_Error("Unable to load source '%s' ", url_string);
    }
  }

  // Handle 'part' of IO library.
  if (is_io_library) {
    if (tag == Dart_kSourceTag) {
      return Dart_LoadSource(
          library, url, Builtin::PartSource(Builtin::kIOLibrary, url_string));
    } else {
      ASSERT(tag == Dart_kImportTag);
      return Dart_Error("Unable to import '%s' ", url_string);
    }
  }

  // Handle 'import' or 'part' requests for all other URIs.
  // Get the file path out of the url.
  Dart_Handle builtin_lib =
      Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
  Dart_Handle file_path = FilePathFromUri(url, builtin_lib);
  if (Dart_IsError(file_path)) {
    return file_path;
  }
  Dart_StringToCString(file_path, &url_string);
  if (is_dart_extension_url) {
    if (tag != Dart_kImportTag) {
      return Dart_Error("Dart extensions must use import: '%s'", url_string);
    }
    return Extensions::LoadExtension(url_string, library);
  }
  result = DartUtils::LoadSource(NULL,
                                 library,
                                 url,
                                 tag,
                                 url_string);
  return result;
}


const uint8_t* DartUtils::SniffForMagicNumber(const uint8_t* text_buffer,
                                              intptr_t* buffer_len,
                                              bool* is_snapshot) {
  intptr_t len = sizeof(magic_number);
  for (intptr_t i = 0; i < len; i++) {
    if (text_buffer[i] != magic_number[i]) {
      *is_snapshot = false;
      return text_buffer;
    }
  }
  *is_snapshot = true;
  ASSERT(*buffer_len > len);
  *buffer_len -= len;
  return text_buffer + len;
}


void DartUtils::WriteMagicNumber(File* file) {
  // Write a magic number and version information into the snapshot file.
  bool bytes_written = file->WriteFully(magic_number, sizeof(magic_number));
  ASSERT(bytes_written);
}


Dart_Handle DartUtils::LoadScriptHttp(Dart_Handle uri,
                                      Dart_Handle builtin_lib) {
  const char* host_str = NULL;
  int64_t port_int = 0;
  const char* path_str = NULL;
  Dart_Handle result = ParseHttpUri(uri, &host_str, &port_int,
                                    &path_str);
  if (Dart_IsError(result)) {
    return result;
  }
  const char* error_msg = NULL;
  intptr_t len;
  const uint8_t* text_buffer;
  text_buffer = HttpGetRequest(host_str, path_str, port_int, &len,
                               &error_msg);
  if (text_buffer == NULL) {
    return Dart_Error(error_msg);
  }
  const uint8_t* payload = HttpRequestGetPayload(
      reinterpret_cast<const char*>(text_buffer));
  if (payload == NULL) {
    return Dart_Error("Invalid HTTP response.");
  }
  // Subtract HTTP response from length.
  len -= (payload-text_buffer);
  ASSERT(len >= 0);
  // At this point we have received a valid HTTP 200 reply and
  // payload points at the beginning of the script or snapshot.
  bool is_snapshot = false;
  payload = SniffForMagicNumber(payload, &len, &is_snapshot);
  if (is_snapshot) {
    return Dart_LoadScriptFromSnapshot(payload, len);
  } else {
    Dart_Handle source = Dart_NewStringFromUTF8(payload, len);
    if (Dart_IsError(source)) {
      return source;
    }
    return Dart_LoadScript(uri, source, 0, 0);
  }
}


Dart_Handle DartUtils::LoadScript(const char* script_uri,
                                  Dart_Handle builtin_lib) {
  Dart_Handle resolved_script_uri =
      ResolveScriptUri(NewString(script_uri), builtin_lib);
  if (Dart_IsError(resolved_script_uri)) {
    return resolved_script_uri;
  }
  // Handle http: requests separately.
  if (DartUtils::IsHttpSchemeURL(script_uri)) {
    return LoadScriptHttp(resolved_script_uri, builtin_lib);
  }
  Dart_Handle script_path = DartUtils::FilePathFromUri(resolved_script_uri,
                                                       builtin_lib);
  if (Dart_IsError(script_path)) {
    return script_path;
  }
  const char* script_path_cstr;
  Dart_StringToCString(script_path, &script_path_cstr);
  const char* error_msg = NULL;
  intptr_t len;
  const uint8_t* text_buffer = ReadFileFully(script_path_cstr,
                                             &len,
                                             &error_msg);
  if (text_buffer == NULL) {
    return Dart_Error(error_msg);
  }
  bool is_snapshot = false;
  text_buffer = SniffForMagicNumber(text_buffer, &len, &is_snapshot);
  if (is_snapshot) {
    return Dart_LoadScriptFromSnapshot(text_buffer, len);
  } else {
    Dart_Handle source = Dart_NewStringFromUTF8(text_buffer, len);
    if (Dart_IsError(source)) {
      return source;
    }
    return Dart_LoadScript(resolved_script_uri, source, 0, 0);
  }
}


Dart_Handle DartUtils::LoadSource(CommandLineOptions* url_mapping,
                                  Dart_Handle library,
                                  Dart_Handle url,
                                  Dart_LibraryTag tag,
                                  const char* url_string) {
  bool is_http_scheme_url = DartUtils::IsHttpSchemeURL(url_string);
  if (url_mapping != NULL && IsDartSchemeURL(url_string)) {
    const char* mapped_url_string = MapLibraryUrl(url_mapping, url_string);
    if (mapped_url_string == NULL) {
      return Dart_Error("Do not know how to load %s", url_string);
    }
    // We have a URL mapping specified, just read the file that the
    // URL mapping specifies and load it.
    url_string = mapped_url_string;
  }
  Dart_Handle source;
  if (is_http_scheme_url) {
    // Read the file over http.
    source = DartUtils::ReadStringFromHttp(url_string);
  } else {
    // Read the file.
    source = DartUtils::ReadStringFromFile(url_string);
  }
  if (Dart_IsError(source)) {
    return source;  // source contains the error string.
  }
  // The tag is either an import or a source tag.
  // Load it according to the specified tag.
  if (tag == Dart_kImportTag) {
    // Return library object or an error string.
    return Dart_LoadLibrary(url, source);
  } else if (tag == Dart_kSourceTag) {
    return Dart_LoadSource(library, url, source);
  }
  return Dart_Error("wrong tag");
}


Dart_Handle DartUtils::PrepareForScriptLoading(const char* package_root,
                                               Dart_Handle builtin_lib) {
  // Setup the corelib 'print' function.
  Dart_Handle print = Dart_Invoke(
      builtin_lib, NewString("_getPrintClosure"), 0, 0);
  Dart_Handle corelib = Dart_LookupLibrary(NewString("dart:core"));
  Dart_Handle result = Dart_SetField(corelib,
                                     NewString("_printClosure"),
                                     print);

  // Setup the 'timer' factory.
  Dart_Handle url = NewString(kAsyncLibURL);
  DART_CHECK_VALID(url);
  Dart_Handle async_lib = Dart_LookupLibrary(url);
  DART_CHECK_VALID(async_lib);
  Dart_Handle io_lib = Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
  Dart_Handle timer_closure =
      Dart_Invoke(io_lib, NewString("_getTimerFactoryClosure"), 0, NULL);
  Dart_Handle args[1];
  args[0] = timer_closure;
  DART_CHECK_VALID(Dart_Invoke(
      async_lib, NewString("_setTimerFactoryClosure"), 1, args));


  if (IsWindowsHost()) {
    result = Dart_Invoke(builtin_lib, NewString("_setWindows"), 0, 0);
    if (Dart_IsError(result)) {
      return result;
    }
  }

  if (Dart_IsError(result)) {
    return result;
  }
  // Set current working directory.
  result = SetWorkingDirectory(builtin_lib);
  if (Dart_IsError(result)) {
    return result;
  }

  // Set up package root if specified.
  if (package_root != NULL) {
    result = NewString(package_root);
    if (!Dart_IsError(result)) {
      const int kNumArgs = 1;
      Dart_Handle dart_args[kNumArgs];
      dart_args[0] = result;
      return Dart_Invoke(builtin_lib,
                         NewString("_setPackageRoot"),
                         kNumArgs,
                         dart_args);
    }
  }
  return result;
}


const char* DartUtils::GetCanonicalPath(const char* reference_dir,
                                        const char* filename) {
  if (File::IsAbsolutePath(filename)) {
    return strdup(filename);
  }

  char* canonical_path = File::GetCanonicalPath(reference_dir);
  if  (canonical_path == NULL) {
    canonical_path = strdup(reference_dir);
    ASSERT(canonical_path != NULL);
  }
  ASSERT(File::PathSeparator() != NULL && strlen(File::PathSeparator()) == 1);
  char* path_sep = strrchr(canonical_path, File::PathSeparator()[0]);
  if (path_sep == NULL) {
    // No separator found: Reference is a file in local directory.
    free(canonical_path);
    return strdup(filename);
  }
  *path_sep = '\0';
  intptr_t len = snprintf(NULL, 0, "%s%s%s",
                          canonical_path, File::PathSeparator(), filename);
  char* absolute_filename = reinterpret_cast<char*>(malloc(len + 1));
  ASSERT(absolute_filename != NULL);

  snprintf(absolute_filename, len + 1, "%s%s%s",
           canonical_path, File::PathSeparator(), filename);
  free(canonical_path);
  canonical_path = File::GetCanonicalPath(absolute_filename);
  if (canonical_path == NULL) {
    return absolute_filename;
  }
  free(absolute_filename);
  return canonical_path;
}


bool DartUtils::PostNull(Dart_Port port_id) {
  // Post a message with just the null object.
  return Dart_PostCObject(port_id, CObject::Null()->AsApiCObject());
}


bool DartUtils::PostInt32(Dart_Port port_id, int32_t value) {
  // Post a message with the integer value.
  int32_t min = 0xc0000000;  // -1073741824
  int32_t max = 0x3fffffff;  // 1073741823
  ASSERT(min <= value && value < max);
  Dart_CObject object;
  object.type = Dart_CObject_kInt32;
  object.value.as_int32 = value;
  return Dart_PostCObject(port_id, &object);
}


Dart_Handle DartUtils::GetDartClass(const char* library_url,
                                    const char* class_name) {
  return Dart_GetClass(Dart_LookupLibrary(NewString(library_url)),
                       NewString(class_name));
}


Dart_Handle DartUtils::NewDartOSError() {
  // Extract the current OS error.
  OSError os_error;
  return NewDartOSError(&os_error);
}


Dart_Handle DartUtils::NewDartOSError(OSError* os_error) {
  // Create a dart:io OSError object with the information retrieved from the OS.
  Dart_Handle clazz = GetDartClass(kIOLibURL, "OSError");
  Dart_Handle args[2];
  args[0] = NewString(os_error->message());
  args[1] = Dart_NewInteger(os_error->code());
  return Dart_New(clazz, Dart_Null(), 2, args);
}


Dart_Handle DartUtils::NewDartSocketException(const char* message,
                                              Dart_Handle os_error) {
  // Create a dart:io SocketException object.
  Dart_Handle clazz = GetDartClass(kIOLibURL, "SocketException");
  Dart_Handle args[2];
  args[0] = NewString(message);
  args[1] = os_error;
  return Dart_New(clazz, Dart_Null(), 2, args);
}


Dart_Handle DartUtils::NewDartExceptionWithMessage(const char* library_url,
                                                   const char* exception_name,
                                                   const char* message) {
  // Create a Dart Exception object with a message.
  Dart_Handle clazz = GetDartClass(library_url, exception_name);
  if (message != NULL) {
    Dart_Handle args[1];
    args[0] = NewString(message);
    return Dart_New(clazz, Dart_Null(), 1, args);
  } else {
    return Dart_New(clazz, Dart_Null(), 0, NULL);
  }
}


Dart_Handle DartUtils::NewDartArgumentError(const char* message) {
  return NewDartExceptionWithMessage(kCoreLibURL,
                                     "ArgumentError",
                                     message);
}


Dart_Handle DartUtils::NewInternalError(const char* message) {
  return NewDartExceptionWithMessage(kCoreLibURL, "InternalError", message);
}


void DartUtils::SetOriginalWorkingDirectory() {
  original_working_directory = Directory::Current();
}


// Statically allocated Dart_CObject instances for immutable
// objects. As these will be used by different threads the use of
// these depends on the fact that the marking internally in the
// Dart_CObject structure is not marking simple value objects.
Dart_CObject CObject::api_null_ = { Dart_CObject_kNull , { 0 } };
Dart_CObject CObject::api_true_ = { Dart_CObject_kBool , { true } };
Dart_CObject CObject::api_false_ = { Dart_CObject_kBool, { false } };
CObject CObject::null_ = CObject(&api_null_);
CObject CObject::true_ = CObject(&api_true_);
CObject CObject::false_ = CObject(&api_false_);


CObject* CObject::Null() {
  return &null_;
}


CObject* CObject::True() {
  return &true_;
}


CObject* CObject::False() {
  return &false_;
}


CObject* CObject::Bool(bool value) {
  return value ? &true_ : &false_;
}


Dart_CObject* CObject::New(Dart_CObject_Type type, int additional_bytes) {
  Dart_CObject* cobject = reinterpret_cast<Dart_CObject*>(
      Dart_ScopeAllocate(sizeof(Dart_CObject) + additional_bytes));
  cobject->type = type;
  return cobject;
}


Dart_CObject* CObject::NewInt32(int32_t value) {
  Dart_CObject* cobject = New(Dart_CObject_kInt32);
  cobject->value.as_int32 = value;
  return cobject;
}


Dart_CObject* CObject::NewInt64(int64_t value) {
  Dart_CObject* cobject = New(Dart_CObject_kInt64);
  cobject->value.as_int64 = value;
  return cobject;
}


Dart_CObject* CObject::NewIntptr(intptr_t value) {
  // Pointer values passed as intptr_t are always send as int64_t.
  Dart_CObject* cobject = New(Dart_CObject_kInt64);
  cobject->value.as_int64 = value;
  return cobject;
}


Dart_CObject* CObject::NewDouble(double value) {
  Dart_CObject* cobject = New(Dart_CObject_kDouble);
  cobject->value.as_double = value;
  return cobject;
}


Dart_CObject* CObject::NewString(int length) {
  Dart_CObject* cobject = New(Dart_CObject_kString, length + 1);
  cobject->value.as_string = reinterpret_cast<char*>(cobject + 1);
  return cobject;
}


Dart_CObject* CObject::NewString(const char* str) {
  int length = strlen(str);
  Dart_CObject* cobject = NewString(length);
  memmove(cobject->value.as_string, str, length + 1);
  return cobject;
}


Dart_CObject* CObject::NewArray(int length) {
  Dart_CObject* cobject =
      New(Dart_CObject_kArray, length * sizeof(Dart_CObject*));  // NOLINT
  cobject->value.as_array.length = length;
  cobject->value.as_array.values =
      reinterpret_cast<Dart_CObject**>(cobject + 1);
  return cobject;
}


Dart_CObject* CObject::NewUint8Array(int length) {
  Dart_CObject* cobject = New(Dart_CObject_kTypedData, length);
  cobject->value.as_typed_data.type = Dart_TypedData_kUint8;
  cobject->value.as_typed_data.length = length;
  cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1);
  return cobject;
}


Dart_CObject* CObject::NewExternalUint8Array(
    int64_t length, uint8_t* data, void* peer,
    Dart_WeakPersistentHandleFinalizer callback) {
  Dart_CObject* cobject = New(Dart_CObject_kExternalTypedData);
  cobject->value.as_external_typed_data.type = Dart_TypedData_kUint8;
  cobject->value.as_external_typed_data.length = length;
  cobject->value.as_external_typed_data.data = data;
  cobject->value.as_external_typed_data.peer = peer;
  cobject->value.as_external_typed_data.callback = callback;
  return cobject;
}


Dart_CObject* CObject::NewIOBuffer(int64_t length) {
  uint8_t* data = IOBuffer::Allocate(length);
  return NewExternalUint8Array(length, data, data, IOBuffer::Finalizer);
}


void CObject::FreeIOBufferData(Dart_CObject* cobject) {
  ASSERT(cobject->type == Dart_CObject_kExternalTypedData);
  cobject->value.as_external_typed_data.callback(
      NULL, cobject->value.as_external_typed_data.peer);
  cobject->value.as_external_typed_data.data = NULL;
}


CObject* CObject::IllegalArgumentError() {
  CObjectArray* result = new CObjectArray(CObject::NewArray(1));
  result->SetAt(0, new CObjectInt32(CObject::NewInt32(kArgumentError)));
  return result;
}


CObject* CObject::FileClosedError() {
  CObjectArray* result = new CObjectArray(CObject::NewArray(1));
  result->SetAt(0, new CObjectInt32(CObject::NewInt32(kFileClosedError)));
  return result;
}


CObject* CObject::NewOSError() {
  OSError os_error;
  return NewOSError(&os_error);
}

CObject* CObject::NewOSError(OSError* os_error) {
  CObject* error_message =
      new CObjectString(CObject::NewString(os_error->message()));
  CObjectArray* result = new CObjectArray(CObject::NewArray(3));
  result->SetAt(0, new CObjectInt32(CObject::NewInt32(kOSError)));
  result->SetAt(1, new CObjectInt32(CObject::NewInt32(os_error->code())));
  result->SetAt(2, error_message);
  return result;
}

}  // namespace bin
}  // namespace dart
