/*
 * 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::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");
  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)
{
  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 (!mScriptObject) {
    *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;
    }
    JSContext* cx = NS_REINTERPRET_CAST(JSContext*,
        aContext->GetNativeContext());
    if (!cx) {
      tracer.setFail("can't get JSContext");
      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;
    }
    mScriptObject = newObj;
  }

  *aScriptObject = mScriptObject;
  return NS_OK;
}

NS_IMETHODIMP ExternalWrapper::SetScriptObject(void* aScriptObject)
{
    mScriptObject = 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;
}
