// 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 <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include "embedders/openglui/common/extension.h"
#include "embedders/openglui/common/log.h"
#include "embedders/openglui/common/vm_glue.h"
#include "include/dart_api.h"

char* VMGlue::extension_script_ = NULL;
bool VMGlue::initialized_vm_ = false;

// snapshot_buffer points to a snapshot if we link in a snapshot otherwise
// it is initialized to NULL.

VMGlue::VMGlue(ISized* surface,
               const char* script_path,
               const char* extension_script,
               const char* main_script,
               int setup_flag)
    : surface_(surface),
      isolate_(NULL),
      initialized_script_(false),
      x_(0.0),
      y_(0.0),
      z_(0.0),
      accelerometer_changed_(false),
      setup_flag_(setup_flag) {
  LOGI("Creating VMGlue");
  if (main_script == NULL) {
    main_script = "main.dart";
  }
  if (extension_script == NULL) {
    extension_script = "gl.dart";
  }
  size_t len = strlen(script_path) + strlen(main_script) + 2;
  main_script_ = new char[len];
  snprintf(main_script_, len, "%s/%s", script_path, main_script);
  len = strlen(script_path) + strlen(extension_script) + 2;
  extension_script_ = new char[len];
  snprintf(extension_script_, len, "%s/%s", script_path, extension_script);
}

Dart_Handle VMGlue::CheckError(Dart_Handle handle) {
  if (Dart_IsError(handle)) {
    LOGE("Unexpected Error Handle: %s", Dart_GetError(handle));
    Dart_PropagateError(handle);
  }
  return handle;
}

#define CHECK_RESULT(result)                   \
  if (Dart_IsError(result)) {                  \
    *error = strdup(Dart_GetError(result));    \
    LOGE("%s", *error);                        \
    Dart_ExitScope();                          \
    Dart_ShutdownIsolate();                    \
    return false;                              \
  }

Dart_Handle VMGlue::LibraryTagHandler(Dart_LibraryTag tag,
                                      Dart_Handle library,
                                      Dart_Handle urlHandle) {
  const char* url;
  Dart_StringToCString(urlHandle, &url);
  if (tag == kCanonicalizeUrl) {
    return urlHandle;
  }
  // TODO(vsm): Split this up into separate libraries for 3D, 2D,
  // Touch, Audio, etc.  All builtin libraries should be handled here
  // (or moved into a snapshot).
  if (strcmp(url, "gl.dart") == 0) {
    Dart_Handle source =
        VMGlue::LoadSourceFromFile(extension_script_);
    Dart_Handle library = CheckError(Dart_LoadLibrary(urlHandle, source));
    CheckError(Dart_SetNativeResolver(library, ResolveName));
    return library;
  }
  LOGE("UNIMPLEMENTED: load library %s\n", url);
  return NULL;
}

// Returns true on success, false on failure.
Dart_Isolate VMGlue::CreateIsolateAndSetupHelper(const char* script_uri,
                                         const char* main,
                                         void* data,
                                         char** error) {
  LOGI("Creating isolate %s, %s", script_uri, main);
  Dart_Isolate isolate =
      Dart_CreateIsolate(script_uri, main, NULL, data, error);
  if (isolate == NULL) {
    LOGE("Couldn't create isolate: %s", *error);
    return NULL;
  }

  LOGI("Entering scope");
  Dart_EnterScope();

  // Set up the library tag handler for this isolate.
  LOGI("Setting up library tag handler");
  Dart_Handle result = CheckError(Dart_SetLibraryTagHandler(LibraryTagHandler));
  CHECK_RESULT(result);

  Dart_ExitScope();
  return isolate;
}

Dart_Isolate VMGlue::CreateIsolateAndSetup(const char* script_uri,
  const char* main,
  void* data, char** error) {
  return CreateIsolateAndSetupHelper(script_uri,
                                     main,
                                     data,
                                     error);
}

const char* VM_FLAGS[] = {
  "--enable_type_checks",  // TODO(gram): This should be an option!
  // "--trace_isolates",
  // "--trace_natives",
  // "--trace_compiler",
};

static void* openFileCallback(const char* name, bool write) {
  return fopen(name, write ? "w" : "r");
}

static void readFileCallback(const uint8_t** data, intptr_t* fileLength,
    void* stream) {
  if (!stream) {
    *data = 0;
    *fileLength = 0;
  } else {
    FILE* file = reinterpret_cast<FILE*>(stream);

    // Get the file size.
    fseek(file, 0, SEEK_END);
    *fileLength = ftell(file);
    rewind(file);

    // Allocate data buffer.
    *data = new uint8_t[*fileLength];
    *fileLength = fread(const_cast<uint8_t*>(*data), 1, *fileLength, file);
  }
}

static void writeFileCallback(const void* data, intptr_t length, void* file) {
  fwrite(data, 1, length, reinterpret_cast<FILE*>(file));
}

static void closeFileCallback(void* file) {
  fclose(reinterpret_cast<FILE*>(file));
}

int VMGlue::InitializeVM() {
  // We need the next call to get Dart_Initialize not to bail early.
  LOGI("Setting VM Options");
  Dart_SetVMFlags(sizeof(VM_FLAGS) / sizeof(VM_FLAGS[0]), VM_FLAGS);

  // Initialize the Dart VM, providing the callbacks to use for
  // creating and shutting down isolates.
  LOGI("Initializing Dart");
  if (!Dart_Initialize(CreateIsolateAndSetup,
                       0,
                       0,
                       0,
                       openFileCallback,
                       readFileCallback,
                       writeFileCallback,
                       closeFileCallback)) {
    LOGE("VM initialization failed\n");
    return -1;
  }
  initialized_vm_ = true;

  return 0;
}

Dart_Handle VMGlue::LoadSourceFromFile(const char* url) {
  FILE* file = fopen(url, "r");
  if (file == NULL) {
    LOGE("Main script not found at: %s\n", url);
    return NULL;
  }

  struct stat sb;
  int fd = fileno(file);
  fstat(fd, &sb);
  int length = sb.st_size;
  LOGI("Entry file %s is %d bytes.\n", url, length);

  char* buffer = new char[length+1];
  if (read(fd, buffer, length) < 0) {
    LOGE("Could not read script %s.\n", url);
    return NULL;
  }
  buffer[length] = 0;
  fclose(file);

  Dart_Handle contents = CheckError(Dart_NewStringFromCString(buffer));
  delete[] buffer;
  return contents;
}

int VMGlue::StartMainIsolate() {
  if (!initialized_vm_) {
    int rtn = InitializeVM();
    if (rtn != 0) return rtn;
  }

  // Create an isolate and loads up the application script.
  char* error = NULL;
  if (!CreateIsolateAndSetup(main_script_, "main", NULL, &error)) {
    LOGE("CreateIsolateAndSetup: %s\n", error);
    free(error);
    return -1;
  }
  LOGI("Created isolate");
  isolate_ = Dart_CurrentIsolate();
  Dart_EnterScope();

  Dart_Handle url = CheckError(Dart_NewStringFromCString(main_script_));
  Dart_Handle source = LoadSourceFromFile(main_script_);
  CheckError(Dart_LoadScript(url, source, 0, 0));

  Dart_ExitScope();
  Dart_ExitIsolate();
  return 0;
}

int VMGlue::CallSetup(bool force) {
  // TODO(gram): See if we actually need this flag guard here, or if
  // we can eliminate it along with the need for the force parameter.
  if (!initialized_script_ || force) {
    initialized_script_ = true;
    LOGI("Invoking setup(null, %d,%d,%d)",
        surface_->width(), surface_->height(), setup_flag_);
    Dart_EnterIsolate(isolate_);
    Dart_EnterScope();
    Dart_Handle args[4];
    args[0] = CheckError(Dart_Null());
    args[1] = CheckError(Dart_NewInteger(surface_->width()));
    args[2] = CheckError(Dart_NewInteger(surface_->height()));
    args[3] = CheckError(Dart_NewInteger(setup_flag_));
    int rtn = Invoke("setup", 4, args);

    if (rtn == 0) {
      // Plug in the print handler. It would be nice if we could do this
      // before calling setup, but the call to GetField blows up if we
      // haven't run anything yet.
      Dart_Handle library = CheckError(Dart_LookupLibrary(
          Dart_NewStringFromCString("gl.dart")));
      Dart_Handle print = CheckError(
          Dart_GetField(library, Dart_NewStringFromCString("_printClosure")));
      Dart_Handle corelib = CheckError(Dart_LookupLibrary(
          Dart_NewStringFromCString("dart:core")));
      CheckError(Dart_SetField(corelib,
        Dart_NewStringFromCString("_printClosure"), print));
    }
    Dart_ExitScope();
    Dart_ExitIsolate();
    LOGI("Done setup");
    return rtn;
  }
  return 0;
}

int VMGlue::CallUpdate() {
  if (initialized_script_) {
    // If the accelerometer has changed, first do that
    // event.
    Dart_EnterIsolate(isolate_);
    if (accelerometer_changed_) {
      Dart_Handle args[3];
      LOGI("Invoking onAccelerometer(%f,%f,%f)", x_, y_, z_);
      Dart_EnterScope();
      args[0] = CheckError(Dart_NewDouble(x_));
      args[1] = CheckError(Dart_NewDouble(y_));
      args[2] = CheckError(Dart_NewDouble(z_));
      Invoke("onAccelerometer", 3, args, false);
      Dart_ExitScope();
      accelerometer_changed_ = false;
    }
    Dart_EnterScope();
    int rtn = Invoke("update_", 0, 0);
    Dart_ExitScope();
    Dart_ExitIsolate();
    LOGI("Invoke update_ returns %d", rtn);
    return rtn;
  }
  return -1;
}

int VMGlue::CallShutdown() {
  if (initialized_script_) {
    Dart_EnterIsolate(isolate_);
    Dart_EnterScope();
    int rtn = Invoke("shutdown", 0, 0);
    Dart_ExitScope();
    Dart_ExitIsolate();
    return rtn;
  }
  return -1;
}

int VMGlue::OnMotionEvent(const char* pFunction, int64_t pWhen,
  float pMoveX, float pMoveY) {
  if (initialized_script_) {
    LOGI("Invoking %s", pFunction);
    Dart_EnterIsolate(isolate_);
    Dart_EnterScope();
    Dart_Handle args[3];
    args[0] = CheckError(Dart_NewInteger(pWhen));
    args[1] = CheckError(Dart_NewDouble(pMoveX));
    args[2] = CheckError(Dart_NewDouble(pMoveY));
    int rtn = Invoke(pFunction, 3, args, false);
    Dart_ExitScope();
    Dart_ExitIsolate();
    LOGI("Done %s", pFunction);
    return rtn;
  }
  return -1;
}

int VMGlue::OnKeyEvent(const char* function, int64_t when, int32_t key_code,
                       bool isAltKeyDown, bool isCtrlKeyDown,
                       bool isShiftKeyDown, int32_t repeat) {
  if (initialized_script_) {
    LOGI("Invoking %s(_,%d,...)", function, key_code);
    Dart_EnterIsolate(isolate_);
    Dart_EnterScope();
    Dart_Handle args[6];
    args[0] = CheckError(Dart_NewInteger(when));
    args[1] = CheckError(Dart_NewInteger(key_code));
    args[2] = CheckError(Dart_NewBoolean(isAltKeyDown));
    args[3] = CheckError(Dart_NewBoolean(isCtrlKeyDown));
    args[4] = CheckError(Dart_NewBoolean(isShiftKeyDown));
    args[5] = CheckError(Dart_NewInteger(repeat));
    int rtn = Invoke(function, 6, args, false);
    Dart_ExitScope();
    Dart_ExitIsolate();
    LOGI("Done %s", function);
    return rtn;
  }
  return -1;
}

int VMGlue::Invoke(const char* function,
                   int argc,
                   Dart_Handle* args,
                   bool failIfNotDefined) {
  // Lookup the library of the root script.
  Dart_Handle library = Dart_RootLibrary();
  if (Dart_IsNull(library)) {
     LOGE("Unable to find root library\n");
     return -1;
  }

  Dart_Handle nameHandle = Dart_NewStringFromCString(function);

  Dart_Handle result = Dart_Invoke(library, nameHandle, argc, args);

  if (Dart_IsError(result)) {
    const char* error = Dart_GetError(result);
    LOGE("Invoke %s failed: %s", function, error);
    if (failIfNotDefined) {
      return -1;
    }
  }

  // TODO(vsm): I don't think we need this.
  // Keep handling messages until the last active receive port is closed.
  result = Dart_RunLoop();
  if (Dart_IsError(result)) {
    LOGE("Dart_RunLoop: %s\n", Dart_GetError(result));
    return -1;
  }

  return 0;
}

void VMGlue::FinishMainIsolate() {
  LOGI("Finish main isolate");
  Dart_EnterIsolate(isolate_);
  // Shutdown the isolate.
  Dart_ShutdownIsolate();
  isolate_ = NULL;
  initialized_script_ = false;
}

