// 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/extensions.h"

#include <stdio.h>

#include "bin/dartutils.h"
#include "bin/file.h"
#include "bin/platform.h"
#include "bin/utils.h"
#include "include/dart_api.h"
#include "platform/assert.h"
#include "platform/globals.h"
#include "platform/utils.h"

namespace dart {
namespace bin {

static char PathSeparator() {
  const char* sep = File::PathSeparator();
  ASSERT(strlen(sep) == 1);
  return sep[0];
}

void* Extensions::MakePathAndResolve(const char* dir, const char* name) {
  // First try to find the library with a suffix specifying the architecture.
  {
    const char* path_components[] = {
        dir,
        Platform::LibraryPrefix(),
        name,
        "-",
        Platform::HostArchitecture(),  // arm
        ".",
        Platform::LibraryExtension(),  // so
        NULL,
    };
    const char* library_file = Concatenate(path_components);
    void* library_handle = LoadExtensionLibrary(library_file);
    if (library_handle != NULL) {
      return library_handle;
    }
  }

  // Fall back on a library name without the suffix.
  {
    const char* path_components[] = {
        dir,
        Platform::LibraryPrefix(),
        name,
        ".",
        Platform::LibraryExtension(),  // so
        NULL,
    };
    const char* library_file = Concatenate(path_components);
    return LoadExtensionLibrary(library_file);
  }
}

// IMPORTANT: In the absolute path case, do not extract the filename and search
// for that by passing it to LoadLibrary. That can lead to confusion in
// which the absolute path is wrong, and a different version of the library is
// loaded from the standard location.
void* Extensions::ResolveAbsPathExtension(const char* extension_path) {
  const char* last_slash = strrchr(extension_path, PathSeparator()) + 1;
  char* name = strdup(last_slash);
  char* dir = Utils::StrNDup(extension_path, last_slash - extension_path);
  void* library_handle = MakePathAndResolve(dir, name);
  free(dir);
  free(name);
  return library_handle;
}

void* Extensions::ResolveExtension(const char* extension_directory,
                                   const char* extension_name) {
  // If the path following dart-ext is an absolute path, then only look for the
  // library there.
  if (File::IsAbsolutePath(extension_name)) {
    return ResolveAbsPathExtension(extension_name);
  }

  // If the path following dart-ext is just a file name, first look next to
  // the importing Dart library.
  void* library_handle =
      MakePathAndResolve(extension_directory, extension_name);
  if (library_handle != NULL) {
    return library_handle;
  }

  // Then pass the library name down to the platform. E.g. dlopen will do its
  // own search in standard search locations.
  return MakePathAndResolve("", extension_name);
}

Dart_Handle Extensions::LoadExtension(const char* extension_directory,
                                      const char* extension_name,
                                      Dart_Handle parent_library) {
  void* library_handle = ResolveExtension(extension_directory, extension_name);
  if (library_handle == NULL) {
    return GetError();
  }

  const char* extension = extension_name;
  if (File::IsAbsolutePath(extension_name)) {
    extension = strrchr(extension_name, PathSeparator()) + 1;
  }

  const char* strings[] = {extension, "_Init", NULL};
  const char* init_function_name = Concatenate(strings);
  void* init_function = ResolveSymbol(library_handle, init_function_name);
  Dart_Handle result = GetError();
  if (Dart_IsError(result)) {
    return result;
  }
  ASSERT(init_function != NULL);
  typedef Dart_Handle (*InitFunctionType)(Dart_Handle import_map);
  InitFunctionType fn = reinterpret_cast<InitFunctionType>(init_function);
  return (*fn)(parent_library);
}

// Concatenates a NULL terminated array of strings.
// The returned string is scope allocated.
const char* Extensions::Concatenate(const char** strings) {
  int size = 1;  // null termination.
  for (int i = 0; strings[i] != NULL; i++) {
    size += strlen(strings[i]);
  }
  char* result = reinterpret_cast<char*>(Dart_ScopeAllocate(size));
  int index = 0;
  for (int i = 0; strings[i] != NULL; i++) {
    index += snprintf(result + index, size - index, "%s", strings[i]);
  }
  ASSERT(index == size - 1);
  ASSERT(result[size - 1] == '\0');
  return result;
}

}  // namespace bin
}  // namespace dart
