#include "node_modules.h"
#include <cstdio>
#include "base_object-inl.h"
#include "compile_cache.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_url.h"
#include "path.h"
#include "permission/permission.h"
#include "permission/permission_base.h"
#include "util-inl.h"
#include "v8-fast-api-calls.h"
#include "v8-function-callback.h"
#include "v8-primitive.h"
#include "v8-value.h"
#include "v8.h"

#include "simdjson.h"

namespace node {
namespace modules {

using v8::Array;
using v8::Context;
using v8::External;
using v8::FunctionCallbackInfo;
using v8::HandleScope;
using v8::Integer;
using v8::Isolate;
using v8::Local;
using v8::LocalVector;
using v8::Name;
using v8::NewStringType;
using v8::Null;
using v8::Object;
using v8::ObjectTemplate;
using v8::Primitive;
using v8::PropertyCallbackInfo;
using v8::String;
using v8::Undefined;
using v8::Value;

void BindingData::MemoryInfo(MemoryTracker* tracker) const {
  // Do nothing
}

BindingData::BindingData(Realm* realm,
                         v8::Local<v8::Object> object,
                         InternalFieldInfo* info)
    : SnapshotableObject(realm, object, type_int) {}

bool BindingData::PrepareForSerialization(v8::Local<v8::Context> context,
                                          v8::SnapshotCreator* creator) {
  // Return true because we need to maintain the reference to the binding from
  // JS land.
  return true;
}

InternalFieldInfoBase* BindingData::Serialize(int index) {
  DCHECK_IS_SNAPSHOT_SLOT(index);
  InternalFieldInfo* info =
      InternalFieldInfoBase::New<InternalFieldInfo>(type());
  return info;
}

void BindingData::Deserialize(v8::Local<v8::Context> context,
                              v8::Local<v8::Object> holder,
                              int index,
                              InternalFieldInfoBase* info) {
  DCHECK_IS_SNAPSHOT_SLOT(index);
  HandleScope scope(context->GetIsolate());
  Realm* realm = Realm::GetCurrent(context);
  BindingData* binding = realm->AddBindingData<BindingData>(holder);
  CHECK_NOT_NULL(binding);
}

Local<Array> BindingData::PackageConfig::Serialize(Realm* realm) const {
  auto isolate = realm->isolate();
  const auto ToString = [isolate](std::string_view input) -> Local<Primitive> {
    return String::NewFromUtf8(
               isolate, input.data(), NewStringType::kNormal, input.size())
        .ToLocalChecked();
  };
  Local<Value> values[6] = {
      name.has_value() ? ToString(*name) : Undefined(isolate),
      main.has_value() ? ToString(*main) : Undefined(isolate),
      ToString(type),
      imports.has_value() ? ToString(*imports) : Undefined(isolate),
      exports.has_value() ? ToString(*exports) : Undefined(isolate),
      ToString(file_path),
  };
  return Array::New(isolate, values, 6);
}

const BindingData::PackageConfig* BindingData::GetPackageJSON(
    Realm* realm, std::string_view path, ErrorContext* error_context) {
  auto binding_data = realm->GetBindingData<BindingData>();

  auto cache_entry = binding_data->package_configs_.find(path.data());
  if (cache_entry != binding_data->package_configs_.end()) {
    return &cache_entry->second;
  }

  PackageConfig package_config{};
  package_config.file_path = path;
  // No need to exclude BOM since simdjson will skip it.
  if (ReadFileSync(&package_config.raw_json, path.data()) < 0) {
    return nullptr;
  }
  // In some systems, std::string is annotated to generate an
  // AddressSanitizer: container-overflow error when reading beyond the end of
  // the string even when we are still within the capacity of the string.
  // https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow
  // https://github.com/nodejs/node/issues/55584
  // The next lines are a workaround to avoid this false positive.
  size_t json_length = package_config.raw_json.size();
  package_config.raw_json.append(simdjson::SIMDJSON_PADDING, ' ');
  simdjson::padded_string_view json_view(package_config.raw_json.data(),
                                         json_length,
                                         package_config.raw_json.size());
  // End of workaround

  simdjson::ondemand::document document;
  simdjson::ondemand::object main_object;
  simdjson::error_code error =
      binding_data->json_parser.iterate(json_view).get(document);

  const auto throw_invalid_package_config = [error_context, path, realm]() {
    if (error_context == nullptr) {
      THROW_ERR_INVALID_PACKAGE_CONFIG(
          realm->isolate(), "Invalid package config %s.", path.data());
    } else if (error_context->base.has_value()) {
      auto file_url = ada::parse(error_context->base.value());
      CHECK(file_url);
      auto file_path = url::FileURLToPath(realm->env(), *file_url);
      CHECK(file_path.has_value());
      THROW_ERR_INVALID_PACKAGE_CONFIG(
          realm->isolate(),
          "Invalid package config %s while importing \"%s\" from %s.",
          path.data(),
          error_context->specifier.c_str(),
          file_path->c_str());
    } else {
      THROW_ERR_INVALID_PACKAGE_CONFIG(
          realm->isolate(), "Invalid package config %s.", path.data());
    }

    return nullptr;
  };

  if (error || document.get_object().get(main_object)) {
    return throw_invalid_package_config();
  }

  simdjson::ondemand::raw_json_string key;
  simdjson::ondemand::value value;
  std::string_view field_value;
  simdjson::ondemand::json_type field_type;

  for (auto field : main_object) {
    // Throw error if getting key or value fails.
    if (field.key().get(key) || field.value().get(value)) {
      return throw_invalid_package_config();
    }

    // based on coverity using key with == derefs the raw value
    // avoid derefing if its null
    if (key.raw() == nullptr) continue;

    if (key == "name") {
      // Though there is a key "name" with a corresponding value,
      // the value may not be a string or could be an invalid JSON string
      if (value.get_string(package_config.name)) {
        return throw_invalid_package_config();
      }
    } else if (key == "main") {
      // Omit all non-string values
      USE(value.get_string(package_config.main));
    } else if (key == "exports") {
      if (value.type().get(field_type)) {
        return throw_invalid_package_config();
      }
      switch (field_type) {
        case simdjson::ondemand::json_type::object:
        case simdjson::ondemand::json_type::array: {
          if (value.raw_json().get(field_value)) {
            return throw_invalid_package_config();
          }
          package_config.exports = field_value;
          break;
        }
        case simdjson::ondemand::json_type::string: {
          if (value.get_string(package_config.exports)) {
            return throw_invalid_package_config();
          }
          break;
        }
        default:
          break;
      }
    } else if (key == "imports") {
      if (value.type().get(field_type)) {
        return throw_invalid_package_config();
      }
      switch (field_type) {
        case simdjson::ondemand::json_type::array:
        case simdjson::ondemand::json_type::object: {
          if (value.raw_json().get(field_value)) {
            return throw_invalid_package_config();
          }
          package_config.imports = field_value;
          break;
        }
        case simdjson::ondemand::json_type::string: {
          if (value.get_string(package_config.imports)) {
            return throw_invalid_package_config();
          }
          break;
        }
        default:
          break;
      }
    } else if (key == "type") {
      if (value.get_string().get(field_value)) {
        return throw_invalid_package_config();
      }
      // Only update type if it is "commonjs" or "module"
      // The default value is "none" for backward compatibility.
      if (field_value == "commonjs" || field_value == "module") {
        package_config.type = field_value;
      }
    } else if (key == "scripts") {
      if (value.type().get(field_type)) {
        return throw_invalid_package_config();
      }
      switch (field_type) {
        case simdjson::ondemand::json_type::object: {
          if (value.raw_json().get(field_value)) {
            return throw_invalid_package_config();
          }
          package_config.scripts = field_value;
          break;
        }
        default:
          break;
      }
    }
  }
  // package_config could be quite large, so we should move it instead of
  // copying it.
  auto cached = binding_data->package_configs_.insert(
      {std::string(path), std::move(package_config)});

  return &cached.first->second;
}

void BindingData::ReadPackageJSON(const FunctionCallbackInfo<Value>& args) {
  CHECK_GE(args.Length(), 1);  // path, [is_esm, base, specifier]
  CHECK(args[0]->IsString());  // path

  Realm* realm = Realm::GetCurrent(args);
  auto isolate = realm->isolate();

  BufferValue path(isolate, args[0]);
  bool is_esm = args[1]->IsTrue();
  auto error_context = ErrorContext();
  if (is_esm) {
    CHECK(args[2]->IsUndefined() || args[2]->IsString());  // base
    CHECK(args[3]->IsString());                            // specifier

    if (args[2]->IsString()) {
      Utf8Value base_value(isolate, args[2]);
      error_context.base = base_value.ToString();
    }
    Utf8Value specifier(isolate, args[3]);
    error_context.specifier = specifier.ToString();
  }

  THROW_IF_INSUFFICIENT_PERMISSIONS(
      realm->env(),
      permission::PermissionScope::kFileSystemRead,
      path.ToStringView());

  ToNamespacedPath(realm->env(), &path);
  auto package_json = GetPackageJSON(
      realm, path.ToStringView(), is_esm ? &error_context : nullptr);

  if (package_json == nullptr) {
    return;
  }

  args.GetReturnValue().Set(package_json->Serialize(realm));
}

const BindingData::PackageConfig* BindingData::TraverseParent(
    Realm* realm, const std::filesystem::path& check_path) {
  std::filesystem::path current_path = check_path;
  auto env = realm->env();
  const bool is_permissions_enabled = env->permission()->enabled();

  do {
    current_path = current_path.parent_path();

    // We don't need to try "/"
    if (current_path.parent_path() == current_path) {
      break;
    }

    // Stop the search when the process doesn't have permissions
    // to walk upwards
    if (is_permissions_enabled &&
        !env->permission()->is_granted(
            env,
            permission::PermissionScope::kFileSystemRead,
            current_path.generic_string())) [[unlikely]] {
      return nullptr;
    }

    // Check if the path ends with `/node_modules`
    if (current_path.generic_string().ends_with("/node_modules")) {
      return nullptr;
    }

    auto package_json_path = current_path / "package.json";
    auto package_json =
        GetPackageJSON(realm, package_json_path.string(), nullptr);
    if (package_json != nullptr) {
      return package_json;
    }
  } while (true);

  return nullptr;
}

void BindingData::GetNearestParentPackageJSON(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK_GE(args.Length(), 1);
  CHECK(args[0]->IsString());

  Realm* realm = Realm::GetCurrent(args);
  BufferValue path_value(realm->isolate(), args[0]);
  // Check if the path has a trailing slash. If so, add it after
  // ToNamespacedPath() as it will be deleted by ToNamespacedPath()
  bool slashCheck = path_value.ToStringView().ends_with(kPathSeparator);

  ToNamespacedPath(realm->env(), &path_value);

  std::string path_value_str = path_value.ToString();
  if (slashCheck) {
    path_value_str.push_back(kPathSeparator);
  }

  std::filesystem::path path;

#ifdef _WIN32
  std::wstring wide_path = ConvertToWideString(path_value_str, GetACP());
  path = std::filesystem::path(wide_path);
#else
  path = std::filesystem::path(path_value_str);
#endif

  auto package_json = TraverseParent(realm, path);

  if (package_json != nullptr) {
    args.GetReturnValue().Set(package_json->Serialize(realm));
  }
}

void BindingData::GetNearestParentPackageJSONType(
    const FunctionCallbackInfo<Value>& args) {
  CHECK_GE(args.Length(), 1);
  CHECK(args[0]->IsString());

  Realm* realm = Realm::GetCurrent(args);
  BufferValue path_value(realm->isolate(), args[0]);
  // Check if the path has a trailing slash. If so, add it after
  // ToNamespacedPath() as it will be deleted by ToNamespacedPath()
  bool slashCheck = path_value.ToStringView().ends_with(kPathSeparator);

  ToNamespacedPath(realm->env(), &path_value);

  std::string path_value_str = path_value.ToString();
  if (slashCheck) {
    path_value_str.push_back(kPathSeparator);
  }

  std::filesystem::path path;

#ifdef _WIN32
  std::wstring wide_path = ConvertToWideString(path_value_str, GetACP());
  path = std::filesystem::path(wide_path);
#else
  path = std::filesystem::path(path_value_str);
#endif

  auto package_json = TraverseParent(realm, path);

  if (package_json == nullptr) {
    return;
  }

  Local<Value> value;
  if (ToV8Value(realm->context(), package_json->type).ToLocal(&value)) {
    args.GetReturnValue().Set(value);
  }
}

template <bool return_only_type>
void BindingData::GetPackageScopeConfig(
    const FunctionCallbackInfo<Value>& args) {
  CHECK_GE(args.Length(), 1);
  CHECK(args[0]->IsString());

  Realm* realm = Realm::GetCurrent(args);
  Utf8Value resolved(realm->isolate(), args[0]);
  auto package_json_url_base = ada::parse(resolved.ToStringView());
  if (!package_json_url_base) {
    url::ThrowInvalidURL(realm->env(), resolved.ToStringView(), std::nullopt);
    return;
  }
  auto package_json_url =
      ada::parse("./package.json", &package_json_url_base.value());
  if (!package_json_url) {
    url::ThrowInvalidURL(realm->env(), "./package.json", resolved.ToString());
    return;
  }

  std::string_view node_modules_package_path = "/node_modules/package.json";
  auto error_context = ErrorContext();
  error_context.is_esm = true;

  // TODO(@anonrig): Rewrite this function and avoid calling URL parser.
  while (true) {
    auto pathname = package_json_url->get_pathname();
    if (pathname.ends_with(node_modules_package_path)) {
      break;
    }

    auto file_url = url::FileURLToPath(realm->env(), *package_json_url);
    if (!file_url) {
      url::ThrowInvalidURL(realm->env(), resolved.ToStringView(), std::nullopt);
      return;
    }
    error_context.specifier = resolved.ToString();
    auto package_json = GetPackageJSON(realm, *file_url, &error_context);
    if (package_json != nullptr) {
      if constexpr (return_only_type) {
        Local<Value> value;
        if (ToV8Value(realm->context(), package_json->type).ToLocal(&value)) {
          args.GetReturnValue().Set(value);
        }
        return;
      } else {
        return args.GetReturnValue().Set(package_json->Serialize(realm));
      }
    }

    auto last_href = std::string(package_json_url->get_href());
    auto last_pathname = std::string(package_json_url->get_pathname());
    package_json_url = ada::parse("../package.json", &package_json_url.value());
    if (!package_json_url) {
      url::ThrowInvalidURL(realm->env(), "../package.json", last_href);
      return;
    }

    // Terminates at root where ../package.json equals ../../package.json
    // (can't just check "/package.json" for Windows support).
    if (package_json_url->get_pathname() == last_pathname) {
      break;
    }
  }

  if constexpr (return_only_type) {
    return;
  }

  // If the package.json could not be found return a string containing a path
  // to the non-existent package.json file in the initial requested location
  auto package_json_url_as_path =
      url::FileURLToPath(realm->env(), *package_json_url);
  CHECK(package_json_url_as_path);
  Local<Value> ret;
  if (ToV8Value(realm->context(), *package_json_url_as_path, realm->isolate())
          .ToLocal(&ret)) {
    args.GetReturnValue().Set(ret);
  }
}

void FlushCompileCache(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  Local<Context> context = isolate->GetCurrentContext();
  Environment* env = Environment::GetCurrent(context);

  if (!args[0]->IsBoolean() && !args[0]->IsUndefined()) {
    THROW_ERR_INVALID_ARG_TYPE(env,
                               "keepDeserializedCache should be a boolean");
    return;
  }
  Debug(env,
        DebugCategory::COMPILE_CACHE,
        "[compile cache] module.flushCompileCache() requested.\n");
  env->FlushCompileCache();
  Debug(env,
        DebugCategory::COMPILE_CACHE,
        "[compile cache] module.flushCompileCache() finished.\n");
}

void EnableCompileCache(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  Local<Context> context = isolate->GetCurrentContext();
  Environment* env = Environment::GetCurrent(context);
  if (!args[0]->IsString()) {
    THROW_ERR_INVALID_ARG_TYPE(env, "cacheDir should be a string");
    return;
  }
  Utf8Value value(isolate, args[0]);
  CompileCacheEnableResult result = env->EnableCompileCache(*value);
  Local<Value> values[3];
  values[0] = v8::Integer::New(isolate, static_cast<uint8_t>(result.status));
  if (ToV8Value(context, result.message).ToLocal(&values[1]) &&
      ToV8Value(context, result.cache_directory).ToLocal(&values[2])) {
    args.GetReturnValue().Set(
        Array::New(isolate, &values[0], arraysize(values)));
  }
}

void GetCompileCacheDir(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  Local<Context> context = isolate->GetCurrentContext();
  Environment* env = Environment::GetCurrent(context);
  if (!env->use_compile_cache()) {
    args.GetReturnValue().Set(v8::String::Empty(isolate));
    return;
  }

  Local<Value> ret;
  if (ToV8Value(context, env->compile_cache_handler()->cache_dir())
          .ToLocal(&ret)) {
    args.GetReturnValue().Set(ret);
  }
}

void GetCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  CHECK(args[0]->IsString());  // TODO(joyeecheung): accept buffer.
  CHECK(args[1]->IsString());
  CHECK(args[2]->IsUint32());
  Local<Context> context = isolate->GetCurrentContext();
  Environment* env = Environment::GetCurrent(context);
  if (!env->use_compile_cache()) {
    return;
  }
  Local<String> source = args[0].As<String>();
  Local<String> filename = args[1].As<String>();
  CachedCodeType type =
      static_cast<CachedCodeType>(args[2].As<v8::Uint32>()->Value());
  auto* cache_entry =
      env->compile_cache_handler()->GetOrInsert(source, filename, type);
  if (cache_entry == nullptr) {
    return;
  }

  v8::LocalVector<v8::Name> names(isolate,
                                  {FIXED_ONE_BYTE_STRING(isolate, "external")});
  v8::LocalVector<v8::Value> values(isolate,
                                    {v8::External::New(isolate, cache_entry)});
  if (cache_entry->cache != nullptr) {
    Debug(env,
          DebugCategory::COMPILE_CACHE,
          "[compile cache] retrieving transpile cache for %s %s...",
          cache_entry->type_name(),
          cache_entry->source_filename);

    std::string_view cache(
        reinterpret_cast<const char*>(cache_entry->cache->data),
        cache_entry->cache->length);
    Local<Value> transpiled;
    // TODO(joyeecheung): convert with simdutf and into external strings
    if (!ToV8Value(context, cache).ToLocal(&transpiled)) {
      Debug(env, DebugCategory::COMPILE_CACHE, "failed\n");
      return;
    } else {
      Debug(env, DebugCategory::COMPILE_CACHE, "success\n");
    }
    names.push_back(FIXED_ONE_BYTE_STRING(isolate, "transpiled"));
    values.push_back(transpiled);
  } else {
    Debug(env,
          DebugCategory::COMPILE_CACHE,
          "[compile cache] no transpile cache for %s %s\n",
          cache_entry->type_name(),
          cache_entry->source_filename);
  }
  args.GetReturnValue().Set(Object::New(
      isolate, v8::Null(isolate), names.data(), values.data(), names.size()));
}

static void PathHelpersLazyGetter(Local<v8::Name> name,
                                  const PropertyCallbackInfo<Value>& info) {
  Isolate* isolate = info.GetIsolate();
  // This getter has no JavaScript function representation and is not
  // invoked in the creation context.
  // When this getter is invoked in a vm context, the `Realm::GetCurrent(info)`
  // returns a nullptr and retrieve the creation context via `this` object and
  // get the creation Realm.
  Local<Value> receiver_val = info.This();
  if (!receiver_val->IsObject()) {
    THROW_ERR_INVALID_INVOCATION(isolate);
    return;
  }
  Local<Object> receiver = receiver_val.As<Object>();
  Local<Context> context;
  if (!receiver->GetCreationContext().ToLocal(&context)) {
    THROW_ERR_INVALID_INVOCATION(isolate);
    return;
  }
  Environment* env = Environment::GetCurrent(context);

  node::Utf8Value url(isolate, info.Data());
  auto file_url = ada::parse(url.ToStringView());
  CHECK(file_url);
  auto file_path = url::FileURLToPath(env, *file_url);
  CHECK(file_path.has_value());
  std::string_view ret_view = file_path.value();

  node::Utf8Value utf8name(isolate, name);
  auto plain_name = utf8name.ToStringView();
  if (plain_name == "dirname") {
#ifdef _WIN32
#define PATH_SEPARATOR '\\'
#else
#define PATH_SEPARATOR '/'
#endif
    auto index = ret_view.rfind(PATH_SEPARATOR);
    CHECK(index != std::string_view::npos);
    ret_view.remove_suffix(ret_view.size() - index);
#undef PATH_SEPARATOR
  }
  Local<Value> ret;
  if (!ToV8Value(context, ret_view, isolate).ToLocal(&ret)) {
    return;
  }
  info.GetReturnValue().Set(ret);
}
void InitImportMetaPathHelpers(const FunctionCallbackInfo<Value>& args) {
  // target, url, shouldSetDirnameAndFilename, resolve
  CHECK_GE(args.Length(), 2);
  CHECK(args[0]->IsObject());
  CHECK(args[1]->IsString());

  Isolate* isolate = args.GetIsolate();
  Local<Context> context = isolate->GetCurrentContext();
  Environment* env = Environment::GetCurrent(context);

  auto target = args[0].As<Object>();

  // N.B.: Order is important to keep keys in alphabetical order.
  if (target
          ->SetLazyDataProperty(
              context, env->dirname_string(), PathHelpersLazyGetter, args[1])
          .IsNothing() ||
      target
          ->SetLazyDataProperty(
              context, env->filename_string(), PathHelpersLazyGetter, args[1])
          .IsNothing())
    return;
}
void SaveCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  Local<Context> context = isolate->GetCurrentContext();
  Environment* env = Environment::GetCurrent(context);
  DCHECK(env->use_compile_cache());
  CHECK(args[0]->IsExternal());
  CHECK(args[1]->IsString());  // TODO(joyeecheung): accept buffer.
  auto* cache_entry =
      static_cast<CompileCacheEntry*>(args[0].As<External>()->Value());
  Utf8Value utf8(isolate, args[1].As<String>());
  env->compile_cache_handler()->MaybeSave(cache_entry, utf8.ToStringView());
}

void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
                                             Local<ObjectTemplate> target) {
  Isolate* isolate = isolate_data->isolate();
  SetMethod(isolate, target, "readPackageJSON", ReadPackageJSON);
  SetMethod(isolate,
            target,
            "getNearestParentPackageJSONType",
            GetNearestParentPackageJSONType);
  SetMethod(isolate,
            target,
            "getNearestParentPackageJSON",
            GetNearestParentPackageJSON);
  SetMethod(
      isolate, target, "getPackageScopeConfig", GetPackageScopeConfig<false>);
  SetMethod(isolate, target, "getPackageType", GetPackageScopeConfig<true>);
  SetMethod(isolate, target, "enableCompileCache", EnableCompileCache);
  SetMethod(isolate, target, "getCompileCacheDir", GetCompileCacheDir);
  SetMethod(isolate, target, "flushCompileCache", FlushCompileCache);
  SetMethod(isolate, target, "getCompileCacheEntry", GetCompileCacheEntry);
  SetMethod(isolate, target, "saveCompileCacheEntry", SaveCompileCacheEntry);
  SetMethod(isolate, target, "setLazyPathHelpers", InitImportMetaPathHelpers);
}

void BindingData::CreatePerContextProperties(Local<Object> target,
                                             Local<Value> unused,
                                             Local<Context> context,
                                             void* priv) {
  Realm* realm = Realm::GetCurrent(context);
  realm->AddBindingData<BindingData>(target);

  Isolate* isolate = context->GetIsolate();
  LocalVector<Value> compile_cache_status_values(isolate);

#define V(status)                                                              \
  compile_cache_status_values.push_back(                                       \
      FIXED_ONE_BYTE_STRING(isolate, #status));
  COMPILE_CACHE_STATUS(V)
#undef V

  USE(target->Set(context,
                  FIXED_ONE_BYTE_STRING(isolate, "compileCacheStatus"),
                  Array::New(isolate,
                             compile_cache_status_values.data(),
                             compile_cache_status_values.size())));

  LocalVector<Name> cached_code_type_keys(isolate);
  LocalVector<Value> cached_code_type_values(isolate);

#define V(type, value)                                                         \
  cached_code_type_keys.push_back(FIXED_ONE_BYTE_STRING(isolate, #type));      \
  cached_code_type_values.push_back(Integer::New(isolate, value));             \
  DCHECK_EQ(value, cached_code_type_values.size() - 1);
  CACHED_CODE_TYPES(V)
#undef V

  USE(target->Set(context,
                  FIXED_ONE_BYTE_STRING(isolate, "cachedCodeTypes"),
                  Object::New(isolate,
                              Null(isolate),
                              cached_code_type_keys.data(),
                              cached_code_type_values.data(),
                              cached_code_type_keys.size())));
}

void BindingData::RegisterExternalReferences(
    ExternalReferenceRegistry* registry) {
  registry->Register(ReadPackageJSON);
  registry->Register(GetNearestParentPackageJSONType);
  registry->Register(GetNearestParentPackageJSON);
  registry->Register(GetPackageScopeConfig<false>);
  registry->Register(GetPackageScopeConfig<true>);
  registry->Register(EnableCompileCache);
  registry->Register(GetCompileCacheDir);
  registry->Register(FlushCompileCache);
  registry->Register(GetCompileCacheEntry);
  registry->Register(SaveCompileCacheEntry);
  registry->Register(InitImportMetaPathHelpers);
}

}  // namespace modules
}  // namespace node

NODE_BINDING_CONTEXT_AWARE_INTERNAL(
    modules, node::modules::BindingData::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(
    modules, node::modules::BindingData::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(
    modules, node::modules::BindingData::RegisterExternalReferences)
