#include <JavaScriptCore/JavaScript.h>

#include "js_shell.h"

#include <iostream>
#include <stdio.h>

#ifdef __GNUC__
#include <dlfcn.h>
#define LOAD_SYMBOL(handle, name) dlsym(handle, name)
#else
#error "implement dll loading"
#endif

class JSCShell: public JSShell {

typedef int (*JSCIntializer)(JSGlobalContextRef context, JSObjectRef *module);

public:

  JSCShell() { context = 0; }

  virtual ~JSCShell();

protected:

  virtual bool InitializeEngine();

  virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath);

  virtual bool DisposeEngine();

private:

  JSObjectRef Import(const std::string &moduleName);

  static JSValueRef Print(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex);

  static JSValueRef Require(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex);

  static bool RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback cbFunction);

  static void PrintError(JSContextRef, JSValueRef);

private:

  JSGlobalContextRef context;
};

JSCShell::~JSCShell() {
  if(context != 0) {
    JSGlobalContextRelease(context);
    context = 0;
  }
}

bool JSCShell::InitializeEngine() {
  if(context != 0) {
    JSGlobalContextRelease(context);
    context = 0;
  }
  // TODO: check for initialization errors
  context = JSGlobalContextCreate(NULL);
  if(context == 0) return false;
  JSObjectRef globalObject = JSContextGetGlobalObject(context);

  // store this for later use
  JSClassDefinition __shell_classdef__ = JSClassDefinition();

  JSClassRef __shell_class__ = JSClassCreate(&__shell_classdef__);
  JSObjectRef __shell__ = JSObjectMake(context, __shell_class__, 0);
  bool success = JSObjectSetPrivate(__shell__, (void*) (long) this);
  if (!success) {
    std::cerr << "Could not register the shell in the Javascript context" << std::endl;
    return false;
  }
  JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__");
  JSObjectSetProperty(context, globalObject, shellKey, __shell__, kJSPropertyAttributeReadOnly, NULL);
  JSStringRelease(shellKey);

  JSCShell::RegisterFunction(context, globalObject, "print", JSCShell::Print);
  JSCShell::RegisterFunction(context, globalObject, "require", JSCShell::Require);

  return true;
}

bool JSCShell::ExecuteScript(const std::string& source, const std::string& scriptPath) {
  JSStringRef jsScript;
  JSStringRef sourceURL;
  JSValueRef ex;
  jsScript = JSStringCreateWithUTF8CString(source.c_str());
  sourceURL = JSStringCreateWithUTF8CString(scriptPath.c_str());
  JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, sourceURL, 0, &ex);
  JSStringRelease(jsScript);
  if (jsResult == NULL && ex != NULL) {
      JSCShell::PrintError(context, ex);
      return false;
  }
  return true;
}

bool JSCShell::DisposeEngine() {
  JSGlobalContextRelease(context);
  context = 0;
  return true;
}

JSValueRef JSCShell::Print(JSContextRef context, JSObjectRef object,
                           JSObjectRef globalobj, size_t argc,
                           const JSValueRef args[], JSValueRef* ex) {
  if (argc > 0)
  {
    JSStringRef string = JSValueToStringCopy(context, args[0], NULL);
    size_t numChars = JSStringGetMaximumUTF8CStringSize(string);
    char *stringUTF8 = new char[numChars];
    JSStringGetUTF8CString(string, stringUTF8, numChars);
    printf("%s\n", stringUTF8);

    delete[] stringUTF8;
  }

  return JSValueMakeUndefined(context);
}

// Attention: this feature should not create too high expectations.
// It is only capable of loading things relative to the execution directory
// and not relative to the parent script.
JSValueRef JSCShell::Require(JSContextRef context, JSObjectRef object,
                           JSObjectRef globalObj, size_t argc,
                           const JSValueRef args[], JSValueRef* ex) {
  JSObjectRef module;

  JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__");
  JSValueRef shellAsVal = JSObjectGetProperty(context, globalObj, shellKey, NULL);
  JSStringRelease(shellKey);
  JSObjectRef shell = JSValueToObject(context, shellAsVal, 0);
  JSCShell *_this = (JSCShell*) (long) JSObjectGetPrivate(shell);

  if (argc > 0)
  {
    JSStringRef string = JSValueToStringCopy(context, args[0], NULL);
    size_t numChars = JSStringGetMaximumUTF8CStringSize(string);
    char *stringUTF8 = new char[numChars];
    JSStringGetUTF8CString(string, stringUTF8, numChars);

    std::string modulePath(stringUTF8);
    module = _this->Import(modulePath);

    delete[] stringUTF8;
  }

  if (module) {
    return module;
  } else {
    printf("Ooops.\n");
    return JSValueMakeUndefined(context);
  }
}

JSObjectRef JSCShell::Import(const std::string& module_path) {

  HANDLE library;
  std::string module_name = LoadModule(module_path, &library);

  if (library == 0) {
    printf("Could not load module.");
    return 0;
  }

  std::string symname = std::string(module_name).append("_initialize");

  JSCIntializer init_function = reinterpret_cast<JSCIntializer>((long) LOAD_SYMBOL(library, symname.c_str()));
  if(init_function == 0) {
    printf("Could not find module's initializer function.");
    return 0;
  }

  JSObjectRef module;
  init_function(context, &module);

  return module;
}

bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object,
                        const char* functionName, JSObjectCallAsFunctionCallback callback) {
    JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName);
    JSObjectSetProperty(context, object, js_functionName,
                        JSObjectMakeFunctionWithCallback(context, js_functionName, callback),
                        kJSPropertyAttributeNone, NULL);
    JSStringRelease(js_functionName);
    return true;
}

void JSCShell::PrintError(JSContextRef ctx, JSValueRef err) {
  char *buffer;
  size_t length;

  JSStringRef string = JSValueToStringCopy(ctx, err, 0);
  length = JSStringGetLength(string);
  buffer   = new char[length+1];
  JSStringGetUTF8CString(string, buffer, length+1);
  std::string errMsg(buffer);
  JSStringRelease(string);
  delete[] buffer;

  JSObjectRef errObj = JSValueToObject(ctx, err, 0);

  if(errObj == 0) {
    std::cerr << errMsg << std::endl;
    return;
  }

  JSStringRef sourceURLKey = JSStringCreateWithUTF8CString("sourceURL");
  JSStringRef sourceURLStr = JSValueToStringCopy(ctx, JSObjectGetProperty(ctx, errObj, sourceURLKey, 0), 0);
  length = JSStringGetLength(sourceURLStr);
  buffer   = new char[length+1];
  JSStringGetUTF8CString(sourceURLStr, buffer, length+1);
  std::string sourceURL(buffer);
  delete[] buffer;
  JSStringRelease(sourceURLStr);
  JSStringRelease(sourceURLKey);

  JSStringRef lineKey = JSStringCreateWithUTF8CString("line");
  JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0);
  int line = (int) JSValueToNumber(ctx, jsLine, 0);
  JSStringRelease(lineKey);

  std::cerr << sourceURL << ':' << line << ':' << errMsg << std::endl;
}

JSShell* JSCShell_Create() {
  return new JSCShell();
}
