// 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",
};

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,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL)) {
    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;
}

