/*
 * Copyright 2007 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.
 */

/*
 * Defines the JavaScript class gwt_external_class, which interface via JNI
 * to Java objects.
 */

#include <jni.h>
#include "JsRootedValue.h"
#include "gwt-jni.h"
#include "ExternalWrapper.h"
#include "Tracer.h"
#include "JsStringWrap.h"

// note that this does not use the NS_DEFINE_CID macro because it defines
// the variable as const, which by default has internal linkage.  I could
// work around it by putting extern in front of the macro, but that seems
// fragile if the macro changes.
nsCID kGwtExternalCID = GWT_EXTERNAL_FACTORY_CID;

/*
 * definition of JavaScript gwtOnLoad method which maps to the Java
 * gwtOnLoad method.
 */
static JSBool gwtOnLoad(JSContext *cx, JSObject *obj, uintN argc,
    jsval *argv, jsval *rval)
{
  Tracer tracer("gwtOnLoad");
  tracer.log("context=%08x", unsigned(cx));
  JsRootedValue::ContextManager context(cx);
  JsRootedValue::ensureRuntime(cx);
  if (argc < 2) {
    tracer.setFail("less than 2 args");
    return JS_FALSE;
  }

  JSObject* scriptWindow = 0;
  if (argv[0] != JSVAL_NULL && argv[0] != JSVAL_VOID) {
    if (!JS_ValueToObject(cx, argv[0], &scriptWindow)) {
      tracer.setFail("can't get script window object");
      return JS_FALSE;
    }
  }

  JSString* moduleName = 0;
  if (argv[1] != JSVAL_NULL && argv[1] != JSVAL_VOID) {
    moduleName = JS_ValueToString(cx, argv[1]);
  }

  nsCOMPtr<nsIScriptGlobalObject> scriptGlobal(0);
  if (scriptWindow) {
    nsCOMPtr<nsIXPConnect> xpConnect = do_GetService(nsIXPConnect::GetCID());
    nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
    xpConnect->GetWrappedNativeOfJSObject(cx, scriptWindow,
        getter_AddRefs(wrappedNative));
    if (wrappedNative) {
        nsCOMPtr<nsISupports> native;
        wrappedNative->GetNative(getter_AddRefs(native));
        scriptGlobal = do_QueryInterface(native);
    }
  }
  jstring jModuleName(0);
  if (moduleName) {
    jModuleName = savedJNIEnv->NewString(JS_GetStringChars(moduleName),
        JS_GetStringLength(moduleName));
    if (!jModuleName || savedJNIEnv->ExceptionCheck()) {
      tracer.setFail("can't get module name in Java string");
      return JS_FALSE;
    }
    tracer.log("module name=%s", JS_GetStringBytes(moduleName));
  } else {
  	tracer.log("null module name");
  }
  
  jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
  jclass objClass = savedJNIEnv->GetObjectClass(externalObject);
  if (!objClass || savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("can't get LowLevelMoz.ExternalObject class");
    return JS_FALSE;
  }
  
  jmethodID methodID = savedJNIEnv->GetMethodID(objClass, "gwtOnLoad",
      "(ILjava/lang/String;)Z");
  if (!methodID || savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("can't get gwtOnLoad method");
    return JS_FALSE;
  }
  
  tracer.log("scriptGlobal=%08x", unsigned(scriptGlobal.get()));
  
  jboolean result = savedJNIEnv->CallBooleanMethod(externalObject, methodID,
      NS_REINTERPRET_CAST(jint, scriptGlobal.get()), jModuleName);
  if (savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("LowLevelMoz.ExternalObject.gwtOnLoad() threw an exception");
    return JS_FALSE;
  }
  *rval = BOOLEAN_TO_JSVAL((result == JNI_FALSE) ? JS_FALSE : JS_TRUE);
  return JS_TRUE;
}

/*=======================================================================*/
/* Implementation of the getProperty, setProperty, and finalize methods  */
/* for the JavaScript class gwt_external_class.                          */
/*=======================================================================*/

static JSBool JS_DLL_CALLBACK gwt_external_getProperty(JSContext *cx,
    JSObject *obj, jsval id, jsval *vp)
{
  Tracer tracer("gwt_external_getProperty");
  JsRootedValue::ContextManager context(cx);
  if (*vp != JSVAL_VOID)
    return JS_TRUE;

  if (!JSVAL_IS_STRING(id)) {
    tracer.setFail("not a string");
    return JS_FALSE;
  }
  JsStringWrap jsStr(cx, id);
  tracer.log("obj=%08x, property=%.*s", obj, jsStr.length(), jsStr.bytes());

// All this is for calling resolveReference which only returns void.  So,
// just replace this code to return void for now.  TODO(jat): revisit when
// merging in Toby's code. 
#if 0
  jstring jident = savedJNIEnv->NewString(jsStr.chars(), jsStr.length());
  if (!jident || savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("can't create Java string ");
    return JS_FALSE;
  }
  jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
  jclass objClass = savedJNIEnv->GetObjectClass(externalObject);
  if (!objClass || savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("can't find Java class for JS object");
    return JS_FALSE;
  }

  jmethodID methodID = savedJNIEnv->GetMethodID(objClass, "resolveReference",
      "(Ljava/lang/String;)I");
  if (!methodID || savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("exception getting method for int resolveReference(String)");
    return JS_FALSE;
  }
  int retval = savedJNIEnv->CallIntMethod(externalObject, methodID, jident);
  if (savedJNIEnv->ExceptionCheck()) {
    tracer.setFail("exception calling int resolveReference(String)");
    return JS_FALSE;
  }
  *vp = retval;
#else
  *vp = JSVAL_VOID;
#endif
  return JS_TRUE;
}

static void JS_DLL_CALLBACK gwt_external_finalize(JSContext *cx, JSObject *obj)
{
  // We don't need to push a context if all we do is DeleteGlobalRef
  Tracer tracer("gwt_external_finalize", obj);
  jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
  if (externalObject) {
    savedJNIEnv->DeleteGlobalRef(externalObject);
  }
  JS_FinalizeStub(cx, obj);
}

static JSBool JS_DLL_CALLBACK gwt_external_setProperty(JSContext *cx,
    JSObject *obj, jsval id, jsval *vp)
{
  return JS_FALSE;
}
 
static JSClass gwt_external_class = {
    "gwt_external_class", JSCLASS_HAS_PRIVATE,
    JS_PropertyStub, JS_PropertyStub, gwt_external_getProperty,
    gwt_external_setProperty, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
    gwt_external_finalize,
    JSCLASS_NO_OPTIONAL_MEMBERS
};

NS_IMPL_ISUPPORTS1(ExternalWrapper, nsIScriptObjectOwner)

/*
 * Create a new LowLevelMoz.ExternalObject instance and a JavaScript object
 * that refers to it, mapping the gwtOnLoad member function mapping to
 * a Javascript method.
 */
NS_IMETHODIMP ExternalWrapper::GetScriptObject(nsIScriptContext *aContext,
    void** aScriptObject)
{
  Tracer tracer("ExternalWrapper::GetScriptObject"); 
  if (!aScriptObject) {
    tracer.setFail("null script object pointer");
    return NS_ERROR_INVALID_POINTER;
  }
  if (!jsWindowExternalObject) {
    JSContext* cx = NS_REINTERPRET_CAST(JSContext*,
        aContext->GetNativeContext());
    if (!cx) {
      tracer.setFail("can't get JSContext");
      return NS_ERROR_UNEXPECTED;
    }
    JsRootedValue::ContextManager context(cx);
    *aScriptObject = 0;

    nsIScriptGlobalObject* globalObject = aContext->GetGlobalObject();
    nsCOMPtr<nsIDOMWindow> domWindow(do_QueryInterface(globalObject));
    if (!domWindow) {
      tracer.setFail("can't get DOM window");
      return NS_ERROR_UNEXPECTED;
    }
    nsCOMPtr<nsIDOMWindow> topWindow;
    domWindow->GetTop(getter_AddRefs(topWindow));
    if (!topWindow) {
      tracer.setFail("Can't get top window");
      return NS_ERROR_UNEXPECTED;
    }

    tracer.log("savedJNIEnv=%08x, llClass=%08x", unsigned(savedJNIEnv),
        lowLevelMozClass);
    
    jmethodID methodID = savedJNIEnv->GetStaticMethodID(lowLevelMozClass,
        "createExternalObjectForDOMWindow",
        "(I)Lcom/google/gwt/dev/shell/moz/LowLevelMoz$ExternalObject;");
    if (!methodID || savedJNIEnv->ExceptionCheck()) {
      tracer.setFail("Can't get createExternalObjectForDOMWindow method");
      return NS_ERROR_UNEXPECTED;
    }

    jobject externalObject = savedJNIEnv->CallStaticObjectMethod(
        lowLevelMozClass, methodID, NS_REINTERPRET_CAST(jint, topWindow.get()));
    if (!externalObject || savedJNIEnv->ExceptionCheck()) {
      tracer.setFail("createExternalObjectForDOMWindow failed");
      return NS_ERROR_UNEXPECTED;
    }
    externalObject = savedJNIEnv->NewGlobalRef(externalObject);
    if (!externalObject || savedJNIEnv->ExceptionCheck()) {
      tracer.setFail("can't get GlobalRef for external object");
      return NS_ERROR_UNEXPECTED;
    }
    JSObject* newObj = JS_NewObject(cx, &gwt_external_class, 0,
        globalObject->GetGlobalJSObject());
    if (!newObj) {
      tracer.setFail("can't create new gwt_external_class object");
      return NS_ERROR_OUT_OF_MEMORY;
    }
    if (!JS_SetPrivate(cx, newObj, externalObject)) {
      savedJNIEnv->DeleteGlobalRef(externalObject);
      tracer.setFail("can't store external object private reference");
      return NS_ERROR_UNEXPECTED;
    }
  
    if (!JS_DefineFunction(cx, newObj, "gwtOnLoad", gwtOnLoad, 3,
        JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
      tracer.setFail("can't define gwtOnLoad function on JavaScript object");
      return NS_ERROR_UNEXPECTED;
    }
    jsWindowExternalObject = newObj;
  }

  *aScriptObject = jsWindowExternalObject;
  return NS_OK;
}

NS_IMETHODIMP ExternalWrapper::SetScriptObject(void* aScriptObject)
{
    jsWindowExternalObject = aScriptObject;
    return NS_OK;
}

NS_IMPL_ISUPPORTS1(nsRpExternalFactory, nsIFactory)

NS_IMETHODIMP nsRpExternalFactory::CreateInstance(nsISupports *aOuter,
    const nsIID& aIID, void** aResult)
{
  Tracer tracer("nsRpExternalFactory::CreateInstance");
  if (!aResult) {
    tracer.setFail("null pointer for return value");
    return NS_ERROR_INVALID_POINTER;
  }
  *aResult  = NULL;

  if (aOuter) {
    tracer.setFail("aOuter is not null");
    return NS_ERROR_NO_AGGREGATION;
  }

  nsISupports* object = new ExternalWrapper();
  if (!object) {
    tracer.setFail("can't create a new ExternalWrapper");
    return NS_ERROR_OUT_OF_MEMORY;
  }
      
  nsresult result = object->QueryInterface(aIID, aResult);
  if (!*aResult || NS_FAILED(result)) {
    tracer.setFail("ExternalWrapper::QueryInterface failed");
    delete object;
  }
  return result;
}

NS_IMETHODIMP nsRpExternalFactory::LockFactory(PRBool lock)
{
    return NS_ERROR_NOT_IMPLEMENTED;
}
