// 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 <stdio.h>

#include "include/dart_api.h"

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/io_natives.h"

namespace dart {
namespace bin {

Builtin::builtin_lib_props Builtin::builtin_libraries_[] = {
    /* { url_, source_, patch_url_, patch_source_, has_natives_ } */
    {DartUtils::kBuiltinLibURL, NULL, NULL, NULL, true},
    {DartUtils::kIOLibURL, NULL, NULL, NULL, true},

    // End marker.
    {NULL, NULL, NULL, NULL, false}};

Dart_Port Builtin::load_port_ = ILLEGAL_PORT;
const int Builtin::num_libs_ =
    sizeof(Builtin::builtin_libraries_) / sizeof(Builtin::builtin_lib_props);

Dart_Handle Builtin::Source(BuiltinLibraryId id) {
  return DartUtils::NewError("Unreachable code in Builtin::Source (%d).", id);
}

Dart_Handle Builtin::PartSource(BuiltinLibraryId id, const char* uri) {
  return DartUtils::NewError("Unreachable code in Builtin::PartSource (%d).",
                             id);
}

Dart_Handle Builtin::GetSource(const char** source_paths, const char* uri) {
  return DartUtils::NewError("Unreachable code in Builtin::GetSource (%s).",
                             uri);
}

void Builtin::SetNativeResolver(BuiltinLibraryId id) {
  ASSERT(static_cast<int>(id) >= 0);
  ASSERT(static_cast<int>(id) < num_libs_);

  if (builtin_libraries_[id].has_natives_) {
    Dart_Handle url = DartUtils::NewString(builtin_libraries_[id].url_);
    Dart_Handle library = Dart_LookupLibrary(url);
    ASSERT(!Dart_IsError(library));
    // Setup the native resolver for built in library functions.
    DART_CHECK_VALID(
        Dart_SetNativeResolver(library, NativeLookup, NativeSymbol));
  }
}

Dart_Handle Builtin::LoadLibrary(Dart_Handle url, BuiltinLibraryId id) {
  return DartUtils::NewError("Unreachable code in Builtin::LoadLibrary (%d).",
                             id);
}

Builtin::BuiltinLibraryId Builtin::FindId(const char* url_string) {
  return kInvalidLibrary;
}

Dart_Handle Builtin::LoadAndCheckLibrary(BuiltinLibraryId id) {
  ASSERT(static_cast<int>(id) >= 0);
  ASSERT(static_cast<int>(id) < num_libs_);

  Dart_Handle url = DartUtils::NewString(builtin_libraries_[id].url_);
  Dart_Handle library = Dart_LookupLibrary(url);
  return library;
}

}  // namespace bin
}  // namespace dart
