/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

#include <string>
#include <sstream>
#include "jni.h"
#include "java-dispatch.h"
#include "trace.h"
#include "JStringWrap.h"

namespace gwt {

  /*
   * Declarations for private functions.
   */
  JSClassRef DispatchObjectClassCreate();

  JSClassRef DispatchMethodClassCreate();

  JSValueRef DispatchObjectGetProperty(JSContextRef, JSObjectRef, JSStringRef,
                                       JSValueRef*);

  JSValueRef DispatchObjectToString(JSContextRef, JSObjectRef, JSObjectRef,
                                    size_t, const JSValueRef*, JSValueRef*);

  bool DispatchObjectSetProperty(JSContextRef, JSObjectRef, JSStringRef,
                                 JSValueRef, JSValueRef*);

  void DispatchObjectFinalize(JSObjectRef);

  JSValueRef DispatchMethodCallAsFunction(JSContextRef, JSObjectRef,
                                          JSObjectRef, size_t,
                                          const JSValueRef*, JSValueRef*);

  JSValueRef DispatchMethodGetToString(JSContextRef, JSObjectRef, JSStringRef,
                                       JSValueRef*);

  JSValueRef DispatchMethodToString(JSContextRef, JSObjectRef, JSObjectRef,
                                    size_t, const JSValueRef*, JSValueRef*);

  void DispatchMethodFinalize(JSObjectRef);

  /*
   * The class definition stuct for DispatchObjects.
   */
  static JSClassDefinition _dispatchObjectClassDef = { 0,
      kJSClassAttributeNone, "DispatchObject", 0, 0, 0, 0,
      DispatchObjectFinalize, 0, DispatchObjectGetProperty,
      DispatchObjectSetProperty, 0, 0, 0, 0, 0, 0 };

  /*
   * The class definition structs for DispatchMethods.
   */
  static JSStaticValue _dispatchMethodStaticValues[] = {
    { "toString", DispatchMethodGetToString, 0, kJSPropertyAttributeNone },
    { 0, 0, 0, 0 }
  };
  static JSClassDefinition _dispatchMethodClassDef = { 0,
      kJSClassAttributeNoAutomaticPrototype, "DispatchMethod", 0,
      _dispatchMethodStaticValues, 0, 0, DispatchMethodFinalize, 0, 0, 0, 0,
      0, DispatchMethodCallAsFunction, 0, 0, 0 };

  /*
   * The classes used to create DispatchObjects and DispatchMethods.
   */
  static JSClassRef _dispatchObjectClass = DispatchObjectClassCreate();
  static JSClassRef _dispatchMethodClass = DispatchMethodClassCreate();

  /*
   * Java class and method references needed to do delegation.
   */
  static JNIEnv* _javaEnv;
  static jclass _javaDispatchObjectClass;
  static jclass _javaDispatchMethodClass;
  static jmethodID _javaDispatchObjectSetFieldMethod;
  static jmethodID _javaDispatchObjectGetFieldMethod;
  static jmethodID _javaDispatchMethodInvokeMethod;
  static jmethodID _javaDispatchObjectToStringMethod;

  /*
   * Structure to hold DispatchMethod private data.
   *
   * NOTE: utf8Name is defensively copied.
   */
  class DispatchMethodData {
   public:
    DispatchMethodData(jobject jObject, std::string& utf8Name)
        : _jObject(jObject), _utf8Name(utf8Name) { }
    ~DispatchMethodData() {
       _javaEnv->DeleteGlobalRef(_jObject);
    }
    jobject _jObject;
    std::string _utf8Name;
  };

/*
 * The following takes the prototype from the Function constructor, this allows
 * us to easily support call and apply on our objects that support CallAsFunction.
 *
 * NOTE: The return value is not protected.
 */
JSValueRef GetFunctionPrototype(JSContextRef jsContext, JSValueRef* exception) {
  TR_ENTER();
  JSObjectRef globalObject = JSContextGetGlobalObject(jsContext);
  JSStringRef fnPropName= JSStringCreateWithUTF8CString("Function");
  JSValueRef fnCtorValue = JSObjectGetProperty(jsContext, globalObject,
      fnPropName, exception);
  JSStringRelease(fnPropName);
  if (!fnCtorValue) {
    return JSValueMakeUndefined(jsContext);
  }

  JSObjectRef fnCtorObject = JSValueToObject(jsContext, fnCtorValue, exception);
  if (!fnCtorObject) {
    return JSValueMakeUndefined(jsContext);
  }

  JSStringRef protoPropName = JSStringCreateWithUTF8CString("prototype");
  JSValueRef fnPrototype = JSObjectGetProperty(jsContext, fnCtorObject,
      protoPropName, exception);
  JSStringRelease(protoPropName);
  if (!fnPrototype) {
    return JSValueMakeUndefined(jsContext);
  }

  TR_LEAVE();
  return fnPrototype;
}

/*
 *
 */
JSClassRef GetDispatchObjectClass() {
  TR_ENTER();
  TR_LEAVE();
  return _dispatchObjectClass;
}

/*
 *
 */
JSClassRef GetDispatchMethodClass() {
  TR_ENTER();
  TR_LEAVE();
  return _dispatchMethodClass;
}

/*
 *
 */
JSClassRef DispatchObjectClassCreate() {
  TR_ENTER();
  JSClassRef dispClass = JSClassCreate(&_dispatchObjectClassDef);
  JSClassRetain(dispClass);
  TR_LEAVE();
  return dispClass;
}

/*
 *
 */
JSClassRef DispatchMethodClassCreate() {
  TR_ENTER();
  JSClassRef dispClass = JSClassCreate(&_dispatchMethodClassDef);
  JSClassRetain(dispClass);
  TR_LEAVE();
  return dispClass;
}

/*
 * NOTE: The object returned from this function is not protected.
 */
JSObjectRef DispatchObjectCreate(JSContextRef jsContext, jobject jObject) {
  TR_ENTER();
  JSObjectRef dispInst = JSObjectMake(jsContext, _dispatchObjectClass,
      _javaEnv->NewGlobalRef(jObject));
  TR_LEAVE();
  return dispInst;
}

/*
 * NOTE: The object returned from this function is not protected.
 */
JSObjectRef DispatchMethodCreate(JSContextRef jsContext, std::string& name,
    jobject jObject) {
  TR_ENTER();
 
  JSObjectRef dispInst = JSObjectMake(jsContext, _dispatchMethodClass,
      new DispatchMethodData(_javaEnv->NewGlobalRef(jObject), name));

  // This could only be cached relative to jsContext.
  JSValueRef fnProtoValue = GetFunctionPrototype(jsContext, NULL);
  JSObjectSetPrototype(jsContext, dispInst, fnProtoValue);
  TR_LEAVE();
  return dispInst;
}

/*
 * NOTE: The value returned from this function is not protected, but all
 * JSValues that are passed into Java are protected before the invocation.
 */
JSValueRef DispatchObjectGetProperty(JSContextRef jsContext,
    JSObjectRef jsObject, JSStringRef jsPropertyName,
    JSValueRef* jsException) {
  TR_ENTER();

  // If you call toString on a DispatchObject, you should get the results
  // of the java object's toString invcation.
  if (JSStringIsEqualToUTF8CString(jsPropertyName, "toString")) {
    JSObjectRef jsFunction = JSObjectMakeFunctionWithCallback(jsContext,
        jsPropertyName, DispatchObjectToString);
    return jsFunction;
  }

  // The class check is omitted because it should not be possible to tear off
  // a getter.
  jobject jObject = reinterpret_cast<jobject>(JSObjectGetPrivate(jsObject));

  jstring jPropertyName = _javaEnv->NewString(
      static_cast<const jchar*>(JSStringGetCharactersPtr(jsPropertyName)),
      static_cast<jsize>(JSStringGetLength(jsPropertyName)));
  if (!jObject || !jPropertyName || _javaEnv->ExceptionCheck()) {
    TR_FAIL();
    _javaEnv->ExceptionClear();
    return JSValueMakeUndefined(jsContext);
  }

  JSValueRef jsResult = reinterpret_cast<JSValueRef>(
      _javaEnv->CallIntMethod(jObject, _javaDispatchObjectGetFieldMethod,
      reinterpret_cast<jint>(jsContext),
      jPropertyName));
  if (!jsResult || _javaEnv->ExceptionCheck()) {
    TR_FAIL();
    _javaEnv->ExceptionClear();
    return JSValueMakeUndefined(jsContext);
  }

  // Java left us an extra reference to eat.
  JSValueUnprotectChecked(jsContext, jsResult);
  TR_LEAVE();
  return jsResult;
}

/*
 *
 */
bool DispatchObjectSetProperty(JSContextRef jsContext, JSObjectRef jsObject,
    JSStringRef jsPropertyName, JSValueRef jsValue, JSValueRef* jsException) {
  TR_ENTER();

  // The class check is omitted because it should not be possible to tear off
  // a getter.
  jobject jObject = reinterpret_cast<jobject>(JSObjectGetPrivate(jsObject));

  jstring jPropertyName = _javaEnv->NewString(
      static_cast<const jchar*>(JSStringGetCharactersPtr(jsPropertyName)),
      static_cast<jsize>(JSStringGetLength(jsPropertyName)));
  if (!jObject || !jPropertyName || _javaEnv->ExceptionCheck()) {
    _javaEnv->ExceptionClear();
    return false;
  }

  JSValueProtectChecked(jsContext, jsValue);

  _javaEnv->CallIntMethod(jObject, _javaDispatchObjectSetFieldMethod,
      reinterpret_cast<jint>(jsContext), jPropertyName,
      reinterpret_cast<jint>(jsValue));
  if (_javaEnv->ExceptionCheck()) {
    _javaEnv->ExceptionClear();
    return false;
  }

  TR_LEAVE();
  return true;
}

/*
 *
 */
void DispatchObjectFinalize(JSObjectRef jsObject) {
  TR_ENTER();
  jobject jObject = reinterpret_cast<jobject>(JSObjectGetPrivate(jsObject));
  _javaEnv->DeleteGlobalRef(jObject);
  TR_LEAVE();
}

/*
 *
 */
void DispatchMethodFinalize(JSObjectRef jsObject) {
  TR_ENTER();
  DispatchMethodData* data = reinterpret_cast<DispatchMethodData*>(
      JSObjectGetPrivate(jsObject));
  delete data;
  TR_LEAVE();
}

/*
 * NOTE: The value returned from this function is not protected.
 */
JSValueRef DispatchObjectToString(JSContextRef jsContext, JSObjectRef,
    JSObjectRef jsThis, size_t, const JSValueRef*, JSValueRef*) {
  TR_ENTER();

  // This function cannot be torn off and applied to any JSValue. If this does
  // not reference a DispatchObject, return undefined.
  if (!JSValueIsObjectOfClass(jsContext, jsThis, GetDispatchObjectClass())) {
    return JSValueMakeUndefined(jsContext);
  }

  jobject jObject = reinterpret_cast<jobject>(JSObjectGetPrivate(jsThis));
  jstring jResult = reinterpret_cast<jstring>(
      _javaEnv->CallObjectMethod(jObject, _javaDispatchObjectToStringMethod));
  if (_javaEnv->ExceptionCheck()) {
    return JSValueMakeUndefined(jsContext);
  } else if (!jResult) {
    return JSValueMakeNull(jsContext);
  } else {
    JStringWrap result(_javaEnv, jResult);
    JSStringRef resultString = JSStringCreateWithCharacters(
        static_cast<const JSChar*>(result.jstr()),
        static_cast<size_t>(result.length()));
    JSValueRef jsResultString = JSValueMakeString(jsContext, resultString);
    JSStringRelease(resultString);
    return jsResultString;
  }
  TR_LEAVE();
}

/*
 *
 */
JSValueRef DispatchMethodCallAsFunction(JSContextRef jsContext,
    JSObjectRef jsFunction, JSObjectRef jsThis, size_t argumentCount,
    const JSValueRef arguments[], JSValueRef* exception) {
  TR_ENTER();

  // We don't need to check the class here because we take the private
  // data from jsFunction and not jsThis.

  DispatchMethodData* data = reinterpret_cast<DispatchMethodData*>(
      JSObjectGetPrivate(jsFunction));
  jobject jObject = data->_jObject;

  jintArray jArguments = _javaEnv->NewIntArray(argumentCount);
  if (!jArguments || _javaEnv->ExceptionCheck()) {
    return JSValueMakeUndefined(jsContext);
  }

  // This single element int array will be passed into the java call to allow the
  // called java method to raise an exception. We will check for a non-null value
  // after the call is dispatched.
  jintArray jException = _javaEnv->NewIntArray(1);
  if (!jException || _javaEnv->ExceptionCheck()) {
    return JNI_FALSE;
  }

  for (size_t i = 0; i < argumentCount; ++i) {
    JSValueRef arg = arguments[i];
    // Java will take ownership of the arguments.
    JSValueProtectChecked(jsContext, arg);
    _javaEnv->SetIntArrayRegion(jArguments, i, 1, reinterpret_cast<jint*>(&arg));
    if (_javaEnv->ExceptionCheck()) {
      return JSValueMakeUndefined(jsContext);
    }
  }

  // Java will take ownership of this.
  JSValueProtectChecked(jsContext, jsThis);

  JSValueRef jsResult = reinterpret_cast<JSValueRef>(_javaEnv->CallIntMethod(jObject,
      _javaDispatchMethodInvokeMethod, reinterpret_cast<jint>(jsContext),
      reinterpret_cast<jint>(jsThis), jArguments, jException));
  if (_javaEnv->ExceptionCheck()) {
    return JSValueMakeUndefined(jsContext);
  }

  JSValueRef jsException = NULL;
  _javaEnv->GetIntArrayRegion(jException, 0, 1, reinterpret_cast<jint*>(&jsException));
  if (!_javaEnv->ExceptionCheck() && jsException) {
    // If the java dispatch set an exception, then we pass it back to our caller.
	if (exception) {
      *exception = jsException;
	}
    // Java left us an extra reference to eat.
    JSValueUnprotectChecked(jsContext, jsException);
  }

  // Java left us an extra reference to eat.
  JSValueUnprotectChecked(jsContext, jsResult);
  TR_LEAVE();
  return jsResult;
}

/*
 * NOTE: The object returned from this function is not protected.
 */
JSValueRef DispatchMethodToString(JSContextRef jsContext, JSObjectRef,
    JSObjectRef thisObject, size_t, const JSValueRef*, JSValueRef*) {
  TR_ENTER();
  
  // This function cannot be torn off and applied to any JSValue. If this does
  // not reference a DispatchMethod, return undefined.
  if (!JSValueIsObjectOfClass(jsContext, thisObject, GetDispatchMethodClass())) {
    return JSValueMakeUndefined(jsContext);
  }

  std::ostringstream ss;
  DispatchMethodData* data = reinterpret_cast<DispatchMethodData*>(
      JSObjectGetPrivate(thisObject));
  ss << "function " << data->_utf8Name << "() {\n    [native code]\n}\n";
  JSStringRef stringRep = JSStringCreateWithUTF8CString(ss.str().c_str());
  JSValueRef jsStringRep = JSValueMakeString(jsContext, stringRep);
  JSStringRelease(stringRep);
  TR_LEAVE();
  return jsStringRep;
}

/*
 * NOTE: The object returned from this function is not protected.
 */
JSValueRef DispatchMethodGetToString(JSContextRef jsContext,
    JSObjectRef jsObject, JSStringRef jsPropertyName, JSValueRef* jsException) {
  TR_ENTER();
  JSObjectRef toStringFn = JSObjectMakeFunctionWithCallback(jsContext,
      jsPropertyName, DispatchMethodToString);
  TR_LEAVE();
  return toStringFn;
}

/*
 *
 */
bool Initialize(JNIEnv* javaEnv, jclass javaDispatchObjectClass,
    jclass javaDispatchMethodClass) {
  TR_ENTER();
  if (!javaEnv || !javaDispatchObjectClass || !javaDispatchMethodClass) {
    return false;
  }

  _javaEnv = javaEnv;
  _javaDispatchObjectClass = static_cast<jclass>(
      javaEnv->NewGlobalRef(javaDispatchObjectClass));
  _javaDispatchMethodClass = static_cast<jclass>(
      javaEnv->NewGlobalRef(javaDispatchMethodClass));
  _javaDispatchObjectSetFieldMethod = javaEnv->GetMethodID(
      javaDispatchObjectClass, "setField", "(ILjava/lang/String;I)V");
  _javaDispatchObjectGetFieldMethod = javaEnv->GetMethodID(
      javaDispatchObjectClass, "getField", "(ILjava/lang/String;)I");
  _javaDispatchMethodInvokeMethod = javaEnv->GetMethodID(
      javaDispatchMethodClass, "invoke", "(II[I[I)I");
  _javaDispatchObjectToStringMethod = javaEnv->GetMethodID(
      javaDispatchObjectClass, "toString", "()Ljava/lang/String;");

  if (!_javaDispatchObjectSetFieldMethod || !_javaDispatchObjectGetFieldMethod
      || !_javaDispatchMethodInvokeMethod || !_javaDispatchObjectToStringMethod
      || javaEnv->ExceptionCheck()) {
    return false;
  }

  TR_LEAVE();
  return true;
}

} // namespace gwt
