// Copyright 2014 The Chromium Authors. 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 <stdlib.h>
#include <string.h>

#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "crypto/random.h"
#include "dart/runtime/include/dart_api.h"
#include "mojo/dart/embedder/builtin.h"
#include "mojo/dart/embedder/mojo_natives.h"

namespace mojo {
namespace dart {

// Lists the native functions implementing basic functionality in
// the Mojo embedder dart, such as printing, and file I/O.
#define BUILTIN_NATIVE_LIST(V)                                                 \
  V(Crypto_GetRandomBytes, 1)                                                  \
  V(Logger_PrintString, 1)                                                     \
  V(Builtin_ReadSync, 1)                                                       \
  V(Builtin_EnumerateFiles, 1)                                                 \
  V(Builtin_LoadScript, 4)                                                     \
  V(Builtin_AsyncLoadError, 3)                                                 \
  V(Builtin_DoneLoading, 0)

BUILTIN_NATIVE_LIST(DECLARE_FUNCTION);

static struct NativeEntries {
  const char* name;
  Dart_NativeFunction function;
  int argument_count;
} BuiltinEntries[] = {BUILTIN_NATIVE_LIST(REGISTER_FUNCTION)};

Dart_NativeFunction Builtin::NativeLookup(Dart_Handle name,
                                          int argument_count,
                                          bool* auto_setup_scope) {
  const char* function_name = nullptr;
  Dart_Handle result = Dart_StringToCString(name, &function_name);
  DART_CHECK_VALID(result);
  DCHECK(function_name != nullptr);
  DCHECK(auto_setup_scope != nullptr);
  *auto_setup_scope = true;
  size_t num_entries = arraysize(BuiltinEntries);
  for (size_t i = 0; i < num_entries; i++) {
    const struct NativeEntries& entry = BuiltinEntries[i];
    if (!strcmp(function_name, entry.name) &&
        (entry.argument_count == argument_count)) {
      return entry.function;
    }
  }
  return nullptr;
}

const uint8_t* Builtin::NativeSymbol(Dart_NativeFunction nf) {
  size_t num_entries = arraysize(BuiltinEntries);
  for (size_t i = 0; i < num_entries; i++) {
    const struct NativeEntries& entry = BuiltinEntries[i];
    if (entry.function == nf) {
      return reinterpret_cast<const uint8_t*>(entry.name);
    }
  }
  return nullptr;
}

// Implementation of native functions which are used for some
// test/debug functionality in standalone dart mode.
void Logger_PrintString(Dart_NativeArguments args) {
  intptr_t length = 0;
  uint8_t* chars = nullptr;
  Dart_Handle str = Dart_GetNativeArgument(args, 0);
  Dart_Handle result = Dart_StringToUTF8(str, &chars, &length);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  } else {
    // Uses fwrite to support printing NUL bytes.
    fwrite(chars, 1, length, stdout);
    fputs("\n", stdout);
  }
  fflush(stdout);
}

void Builtin_ReadSync(Dart_NativeArguments args) {
  intptr_t chars_length = 0;
  uint8_t* chars = nullptr;
  Dart_Handle file_uri = Dart_GetNativeArgument(args, 0);
  if (!Dart_IsString(file_uri)) {
    Dart_PropagateError(file_uri);
  }

  intptr_t file_uri_length = 0;
  Dart_Handle result = Dart_StringLength(file_uri, &file_uri_length);

  result = Dart_StringToUTF8(file_uri, &chars, &chars_length);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  chars[file_uri_length] = '\0';

  base::FilePath path(base::FilePath::FromUTF8Unsafe(
      std::string(reinterpret_cast<char*>(chars))));

  std::string source;
  if (ReadFileToString(path, &source)) {
    Dart_Handle data =
        Dart_NewTypedData(Dart_TypedData_kUint8, source.length());
    char* source_chars = const_cast<char*>(source.c_str());
    Dart_ListSetAsBytes(data, 0, reinterpret_cast<uint8_t*>(source_chars),
                        source.length());
    Dart_SetReturnValue(args, data);
    return;
  }
  LOG(ERROR) << "Failed to read path: " << chars;
  Dart_SetReturnValue(args, Dart_Null());
}

void Builtin_EnumerateFiles(Dart_NativeArguments args) {
  intptr_t chars_length = 0;
  uint8_t* chars = nullptr;
  Dart_Handle path = Dart_GetNativeArgument(args, 0);
  if (!Dart_IsString(path)) {
    Dart_PropagateError(path);
  }

  intptr_t path_length = 0;
  Dart_Handle result = Dart_StringLength(path, &path_length);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }

  result = Dart_StringToUTF8(path, &chars, &chars_length);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }

  chars[path_length] = '\0';
  base::FilePath dir_path(base::FilePath::FromUTF8Unsafe(
      std::string(reinterpret_cast<char*>(chars))));

  std::vector<std::string> entries;
  base::FileEnumerator enumerator(dir_path, false, base::FileEnumerator::FILES);
  while (true) {
    base::FilePath file_path = enumerator.Next();
    std::string file_path_string = file_path.AsUTF8Unsafe();
    if (file_path_string == "") {
      break;
    }
    entries.push_back(file_path_string);
  }

  Dart_Handle list = Dart_NewList(entries.size());
  for (uintptr_t i = 0; i < entries.size(); i++) {
    Dart_Handle entry = Dart_NewStringFromUTF8(
        reinterpret_cast<const uint8_t*>(entries[i].data()),
        entries[i].length());
    Dart_ListSetAt(list, i, entry);
  }
  Dart_SetReturnValue(args, list);
}

// Callback function, gets called from asynchronous script and library
// reading code when there is an i/o error.
void Builtin_AsyncLoadError(Dart_NativeArguments args) {
  //  Dart_Handle source_uri = Dart_GetNativeArgument(args, 0);
  Dart_Handle library_uri = Dart_GetNativeArgument(args, 1);
  Dart_Handle error = Dart_GetNativeArgument(args, 2);
  Dart_Handle library = Dart_LookupLibrary(library_uri);
  // If a library with the given uri exists, give it a chance to handle
  // the error. If the load requests stems from a deferred library load,
  // an IO error is not fatal.
  if (!Dart_IsError(library)) {
    DCHECK(Dart_IsLibrary(library));
    Dart_Handle res = Dart_LibraryHandleError(library, error);
    if (Dart_IsNull(res)) {
      return;
    }
  }
  // The error was not handled above. Propagate an unhandled exception.
  error = Dart_NewUnhandledExceptionError(error);
  Dart_PropagateError(error);
}

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

// Callback function called when the asynchronous load request of a
// script, library or part is complete.
void Builtin_LoadScript(Dart_NativeArguments args) {
  Dart_Handle tag_in = Dart_GetNativeArgument(args, 0);
  Dart_Handle resolved_script_uri = Dart_GetNativeArgument(args, 1);
  Dart_Handle library_uri = Dart_GetNativeArgument(args, 2);
  Dart_Handle source_data = Dart_GetNativeArgument(args, 3);

  Dart_TypedData_Type type = Dart_GetTypeOfExternalTypedData(source_data);
  bool external = type == Dart_TypedData_kUint8;
  uint8_t* data = nullptr;
  intptr_t num_bytes;
  Dart_Handle result = Dart_TypedDataAcquireData(
      source_data, &type, reinterpret_cast<void**>(&data), &num_bytes);
  if (Dart_IsError(result))
    Dart_PropagateError(result);

  scoped_ptr<uint8_t[]> buffer_copy;
  if (!external) {
    // If the buffer is not external, take a copy.
    buffer_copy.reset(new uint8_t[num_bytes]);
    memmove(buffer_copy.get(), data, num_bytes);
    data = buffer_copy.get();
  }

  Dart_TypedDataReleaseData(source_data);

  if (Dart_IsNull(tag_in) && Dart_IsNull(library_uri)) {
    // No tag and a null library_uri indicates this is
    // a top-level script, check if it is a snapshot or a regular
    // script file and load accordingly.
    bool is_snapshot = false;
    const uint8_t* payload =
        SniffForMagicNumber(data, &num_bytes, &is_snapshot);

    if (is_snapshot) {
      result = Dart_LoadScriptFromSnapshot(payload, num_bytes);
    } else {
      Dart_Handle source = Dart_NewStringFromUTF8(data, num_bytes);
      if (Dart_IsError(source)) {
        result = Builtin::NewError("%s is not a valid UTF-8 script",
                                   resolved_script_uri);
      } else {
        result = Dart_LoadScript(resolved_script_uri, source, 0, 0);
      }
    }
  } else {
    int64_t tag = Builtin::GetIntegerValue(tag_in);

    Dart_Handle source = Dart_NewStringFromUTF8(data, num_bytes);
    if (Dart_IsError(source)) {
      result = Builtin::NewError("%s is not a valid UTF-8 script",
                                 resolved_script_uri);
    } else {
      if (tag == Dart_kImportTag) {
        result = Dart_LoadLibrary(resolved_script_uri, source, 0, 0);
      } else {
        DCHECK_EQ(tag, Dart_kSourceTag);
        Dart_Handle library = Dart_LookupLibrary(library_uri);
        DART_CHECK_VALID(library);
        result = Dart_LoadSource(library, resolved_script_uri, source, 0, 0);
      }
    }
  }

  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
}

// Callback function that gets called from dartutils when there are
// no more outstanding load requests.
void Builtin_DoneLoading(Dart_NativeArguments args) {
  Dart_Handle res = Dart_FinalizeLoading(true);
  if (Dart_IsError(res)) {
    Dart_PropagateError(res);
  }
}

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

void Crypto_GetRandomBytes(Dart_NativeArguments args) {
  Dart_Handle count_obj = Dart_GetNativeArgument(args, 0);
  const int64_t kMaxRandomBytes = 4096;
  int64_t count64 = 0;
  if (!GetInt64Value(count_obj, &count64) || (count64 < 0) ||
      (count64 > kMaxRandomBytes)) {
    Dart_Handle error = Dart_NewStringFromCString(
        "Invalid argument: count must be a positive int "
        "less than or equal to 4096.");
    Dart_ThrowException(error);
  }
  intptr_t count = static_cast<intptr_t>(count64);
  scoped_ptr<uint8_t[]> buffer(new uint8_t[count]);

  crypto::RandBytes(reinterpret_cast<void*>(buffer.get()), count);

  Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, count);
  if (Dart_IsError(result)) {
    Dart_Handle error = Dart_NewStringFromCString(
        "Failed to allocate storage.");
    Dart_ThrowException(error);
  }
  Dart_ListSetAsBytes(result, 0, buffer.get(), count);
  Dart_SetReturnValue(args, result);
}

}  // namespace bin
}  // namespace dart
