// Copyright (c) 2017, 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/dfe.h"
#include "bin/dartutils.h"
#include "bin/error_exit.h"
#include "bin/file.h"

#include "vm/kernel.h"

namespace dart {
namespace bin {

const char kPlatformBinaryName[] = "platform.dill";
const char kVMServiceIOBinaryName[] = "vmservice_io.dill";

DFE::DFE()
    : frontend_filename_(NULL),
      platform_binary_filename_(NULL),
      vmservice_io_binary_filename_(NULL),
      kernel_platform_(NULL),
      kernel_vmservice_io_(NULL) {}

DFE::~DFE() {
  frontend_filename_ = NULL;

  if (platform_binary_filename_ != NULL) {
    delete platform_binary_filename_;
    platform_binary_filename_ = NULL;
  }

  if (kernel_platform_ != NULL) {
    delete reinterpret_cast<kernel::Program*>(kernel_platform_);
    kernel_platform_ = NULL;
  }

  if (kernel_vmservice_io_ != NULL) {
    delete reinterpret_cast<kernel::Program*>(kernel_vmservice_io_);
    kernel_vmservice_io_ = NULL;
  }
}

void DFE::SetKernelBinaries(const char* name) {
  intptr_t len = snprintf(NULL, 0, "%s%s%s", name, File::PathSeparator(),
                          kPlatformBinaryName) +
                 1;
  platform_binary_filename_ = new char[len];
  snprintf(platform_binary_filename_, len, "%s%s%s", name,
           File::PathSeparator(), kPlatformBinaryName);

  len = snprintf(NULL, 0, "%s%s%s", name, File::PathSeparator(),
                 kVMServiceIOBinaryName) +
        1;
  vmservice_io_binary_filename_ = new char[len];
  snprintf(vmservice_io_binary_filename_, len, "%s%s%s", name,
           File::PathSeparator(), kVMServiceIOBinaryName);
}

Dart_Handle DFE::ReloadScript(Dart_Isolate isolate, const char* url_string) {
  ASSERT(!Dart_IsServiceIsolate(isolate) && !Dart_IsKernelIsolate(isolate));
  // First check if the URL points to a Kernel IR file in which case we
  // skip the compilation step and directly reload the file.
  const uint8_t* kernel_ir = NULL;
  intptr_t kernel_ir_size = -1;
  if (!TryReadKernelFile(url_string, &kernel_ir, &kernel_ir_size)) {
    // We have a source file, compile it into a kernel ir first.
    // TODO(asiva): We will have to change this API to pass in a list of files
    // that have changed. For now just pass in the main url_string and have it
    // recompile the script.
    Dart_KernelCompilationResult kresult = Dart_CompileToKernel(url_string);
    if (kresult.status != Dart_KernelCompilationStatus_Ok) {
      return Dart_NewApiError(kresult.error);
    }
    kernel_ir = kresult.kernel;
    kernel_ir_size = kresult.kernel_size;
  }
  void* kernel_program = Dart_ReadKernelBinary(kernel_ir, kernel_ir_size);
  ASSERT(kernel_program != NULL);
  Dart_Handle url = Dart_NewStringFromCString(url_string);
  Dart_Handle result = Dart_LoadScript(
      url, Dart_Null(), reinterpret_cast<Dart_Handle>(kernel_program), 0, 0);
  if (Dart_IsError(result)) {
    return result;
  }
  // Finalize loading. This will complete any futures for completed deferred
  // loads.
  result = Dart_FinalizeLoading(true);
  if (Dart_IsError(result)) {
    return result;
  }
  return Dart_Null();
}

void* DFE::CompileAndReadScript(const char* script_uri,
                                char** error,
                                int* exit_code) {
  Dart_KernelCompilationResult result = Dart_CompileToKernel(script_uri);
  switch (result.status) {
    case Dart_KernelCompilationStatus_Ok:
      return Dart_ReadKernelBinary(result.kernel, result.kernel_size);
    case Dart_KernelCompilationStatus_Error:
      *error = result.error;  // Copy error message.
      *exit_code = kCompilationErrorExitCode;
      break;
    case Dart_KernelCompilationStatus_Crash:
      *error = result.error;  // Copy error message.
      *exit_code = kDartFrontendErrorExitCode;
      break;
    case Dart_KernelCompilationStatus_Unknown:
      *error = result.error;  // Copy error message.
      *exit_code = kErrorExitCode;
      break;
  }
  return NULL;
}

void* DFE::ReadPlatform() {
  return kernel_platform_ = ReadScript(platform_binary_filename_);
}

void* DFE::ReadVMServiceIO() {
  return kernel_vmservice_io_ = ReadScript(vmservice_io_binary_filename_);
}

void* DFE::ReadScript(const char* script_uri) {
  const uint8_t* buffer = NULL;
  intptr_t buffer_length = -1;
  bool result = TryReadKernelFile(script_uri, &buffer, &buffer_length);
  if (result) {
    return Dart_ReadKernelBinary(buffer, buffer_length);
  }
  return NULL;
}

bool DFE::TryReadKernelFile(const char* script_uri,
                            const uint8_t** kernel_ir,
                            intptr_t* kernel_ir_size) {
  *kernel_ir = NULL;
  *kernel_ir_size = -1;
  void* script_file = DartUtils::OpenFile(script_uri, false);
  if (script_file != NULL) {
    const uint8_t* buffer = NULL;
    DartUtils::ReadFile(&buffer, kernel_ir_size, script_file);
    DartUtils::CloseFile(script_file);
    if (*kernel_ir_size > 0 && buffer != NULL) {
      // We need a temporary variable because SniffForMagicNumber modifies the
      // buffer pointer to skip snapshot magic number.
      const uint8_t* temp = buffer;
      if (DartUtils::SniffForMagicNumber(&temp, kernel_ir_size) !=
          DartUtils::kKernelMagicNumber) {
        free(const_cast<uint8_t*>(buffer));
        *kernel_ir = NULL;
        *kernel_ir_size = -1;
        return false;
      } else {
        // Do not free buffer if this is a kernel file - kernel_file will be
        // backed by the same memory as the buffer and caller will own it.
        // Caller is responsible for freeing the buffer when this function
        // returns true.
        *kernel_ir = buffer;
        return true;
      }
    }
  }
  return false;
}

}  // namespace bin
}  // namespace dart
