// 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"

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 LoadExtensionLibrary. 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 = StringUtils::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
