/*
 * 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 "JavaObject.h"
#include "FFSessionHandler.h"
#include "SessionData.h"
#include "ServerMethods.h"
#include "Debug.h"
#include "XpcomDebug.h"
#include "HostChannel.h"
#include "InvokeMessage.h"
#include "ReturnMessage.h"
#include "scoped_ptr/scoped_ptr.h"

static JSClass JavaObjectClass = {
  "GWTJavaObject", /* class name */
  JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_NEW_ENUMERATE, /* flags */

  JS_PropertyStub, /* add property */
  JS_PropertyStub, /* delete property */
  JavaObject::getProperty, /* get property */
  JavaObject::setProperty, /* set property */

  reinterpret_cast<JSEnumerateOp>(JavaObject::enumerate), /* enumerate */
  JS_ResolveStub, /* resolve */
  JS_ConvertStub, // JavaObject::convert, /* convert */
  JavaObject::finalize, /* finalize */ //TODO

  NULL, /* object hooks */
  NULL, /* check access */
#if GECKO_VERSION < 2000
  JavaObject::call, /* call */ //TODO
#else
  JavaObject::call20, /* call: compatability wrapper for 2.0+ */
#endif //GECKO_VERSION
  NULL, /* construct */
  NULL, /* object serialization */
  NULL, /* has instance */
  NULL, /* mark */
  NULL /* reserve slots */
};

int JavaObject::getObjectId(JSContext* ctx, JSObject* obj) {
  jsval val;
  JSClass* jsClass = JS_GET_CLASS(ctx, obj);
  if (jsClass != &JavaObjectClass) {
    Debug::log(Debug::Error)
        << "JavaObject::getObjectId called on non-JavaObject: " << jsClass->name
        << Debug::flush;
    return -1;
  }
  if (JSCLASS_RESERVED_SLOTS(jsClass) < 1) {
    Debug::log(Debug::Error)
        << "JavaObject::getObjectId -- " << static_cast<void*>(obj)
        << " has only " << (JSCLASS_RESERVED_SLOTS(jsClass))
        << " reserved slots, no objectId present" << Debug::flush;
    return -1;
  }
  if (!JS_GetReservedSlot(ctx, obj, 0, &val)) {
    Debug::log(Debug::Error) << "Error getting reserved slot" << Debug::flush;
    return -1;
  }
  // TODO: assert JSVAL_IS_INT(val)
  return JSVAL_TO_INT(val);
}

SessionData* JavaObject::getSessionData(JSContext* ctx, JSObject* obj) {
  void* data = JS_GetInstancePrivate(ctx, obj, &JavaObjectClass, NULL);
  return static_cast<SessionData*>(data);
}


bool JavaObject::isJavaObject(JSContext* ctx, JSObject* obj) {
  return JS_GET_CLASS(ctx, obj) == &JavaObjectClass;
}

JSObject* JavaObject::construct(JSContext* ctx, SessionData* data, int objectRef) {
  // TODO: prototype? parent?
  Debug::log(Debug::Spam) << "JavaObject::construct objectId=" << objectRef << Debug::flush;
  JSObject* obj = JS_NewObject(ctx, &JavaObjectClass, NULL, NULL);
  Debug::log(Debug::Spam) << "  obj=" << obj << Debug::flush;
  if (!obj) {
    return NULL;
  }
  // set the session data
  if (!JS_SetPrivate(ctx, obj, data)) {
    Debug::log(Debug::Error) << "Could not set private data" << Debug::flush;
    return NULL;
  }
  // set the objectId
  if (!JS_SetReservedSlot(ctx, obj, 0, INT_TO_JSVAL(objectRef))) {
    Debug::log(Debug::Error) << "Could not set reserved slot" << Debug::flush;
    return NULL;
  }
  // define toString (TODO: some way to avoid doing this each time)
#if GECKO_VERSION < 2000
  if (!JS_DefineFunction(ctx, obj, "toString", JavaObject::toString, 0, 0)) {
    Debug::log(Debug::Error) << "Could not define toString method on object"
        << Debug::flush;
  }
#else
  if (!JS_DefineFunction(ctx, obj, "toString", JavaObject::toString20, 0, 0)) {
    Debug::log(Debug::Error) << "Could not define toString method on object"
        << Debug::flush;
  }
#endif //GECKO_VERSION
  return obj;
}

JSBool JavaObject::getProperty(JSContext* ctx, JSObject* obj, jsid id,
    jsval* rval) {
  Debug::log(Debug::Spam) << "JavaObject::getProperty obj=" << obj << Debug::flush;
  SessionData* data = JavaObject::getSessionData(ctx, obj);
  if (!data) {
    // TODO: replace the frame with an error page instead?
    *rval = JSVAL_VOID;
    return JS_TRUE;
  }
  int objectRef = JavaObject::getObjectId(ctx, obj);
  if (JSID_IS_STRING(id)) {
    JSString* str = JSID_TO_STRING(id);
    if ((JS_GetStringEncodingLength(ctx, str) == 8) && !strncmp("toString",
          JS_EncodeString(ctx, str), 8)) {
      *rval = data->getToStringTearOff();
      return JS_TRUE;
    }
    if ((JS_GetStringEncodingLength(ctx, str) == 2) && !strncmp("id",
          JS_EncodeString(ctx, str), 2)) {
      *rval = INT_TO_JSVAL(objectRef);
      return JS_TRUE;
    }
    if ((JS_GetStringEncodingLength(ctx, str) == 16) && !strncmp("__noSuchMethod__",
          JS_EncodeString(ctx, str), 16)) {
      // Avoid error spew if we are disconnected
      *rval = JSVAL_VOID;
      return JS_TRUE;
    }
    Debug::log(Debug::Error) << "Getting unexpected string property "
        << dumpJsVal(ctx, id) << Debug::flush;
    // TODO: throw a better exception here
    return JS_FALSE;
  }
  if (!JSID_IS_INT(id)) {
    Debug::log(Debug::Error) << "Getting non-int/non-string property "
          << dumpJsVal(ctx, id) << Debug::flush;
    // TODO: throw a better exception here
    return JS_FALSE;
  }
  int dispId = JSID_TO_INT(id);

  HostChannel* channel = data->getHostChannel();
  SessionHandler* handler = data->getSessionHandler();

  Value value = ServerMethods::getProperty(*channel, handler, objectRef, dispId);
  data->makeJsvalFromValue(*rval, ctx, value);
  return JS_TRUE;
}

JSBool JavaObject::setProperty(JSContext* ctx, JSObject* obj, jsid id,
    jsval* vp) {
  Debug::log(Debug::Spam) << "JavaObject::setProperty obj=" << obj << Debug::flush;
  if (!JSID_IS_INT(id)) {
    Debug::log(Debug::Error) << "  Error: setting string property id" << Debug::flush;
    // TODO: throw a better exception here
    return JS_FALSE;
  }

  SessionData* data = JavaObject::getSessionData(ctx, obj);
  if (!data) {
    return JS_TRUE;
  }

  int objectRef = JavaObject::getObjectId(ctx, obj);
  int dispId = JSID_TO_INT(id);

  Value value;
  data->makeValueFromJsval(value, ctx, *vp);

  HostChannel* channel = data->getHostChannel();
  SessionHandler* handler = data->getSessionHandler();

  if (!ServerMethods::setProperty(*channel, handler, objectRef, dispId, value)) {
    // TODO: throw a better exception here
    return JS_FALSE;
  }
  return JS_TRUE;
}

// TODO: can this be removed now?
JSBool JavaObject::convert(JSContext* ctx, JSObject* obj, JSType type, jsval* vp) {
  Debug::log(Debug::Spam) << "JavaObject::convert obj=" << obj
      << " type=" << type << Debug::flush;
  switch (type) {
    case JSTYPE_STRING:
      return toString(ctx, obj, 0, NULL, vp);
    case JSTYPE_VOID:
      *vp = JSVAL_VOID;
      return JS_TRUE;
    case JSTYPE_NULL:
      *vp = JSVAL_NULL;
      return JS_TRUE;
    case JSTYPE_OBJECT:
      *vp = OBJECT_TO_JSVAL(obj);
      return JS_TRUE;
    default:
      break;
  }
  return JS_FALSE;
}

/**
 * List of property names we want to fake on wrapped Java objects.
 */
static const char* propertyNames[] = {
    "toString",
    "id",
};
#define NUM_PROPERTY_NAMES (sizeof(propertyNames) / sizeof(propertyNames[0]))

JSBool JavaObject::enumerate(JSContext* ctx, JSObject* obj, JSIterateOp op,
    jsval* statep, jsid* idp) {
  int objectId = JavaObject::getObjectId(ctx, obj);
  switch (op) {
    case JSENUMERATE_INIT:
      Debug::log(Debug::Spam) << "JavaObject::enumerate(oid=" << objectId
          << ", INIT)" << Debug::flush;
      *statep = JSVAL_ZERO;
      if (idp) {
        *idp = INT_TO_JSID(NUM_PROPERTY_NAMES);
      }
      break;
    case JSENUMERATE_NEXT:
    {
      int idNum = JSVAL_TO_INT(*statep);
      Debug::log(Debug::Spam) << "JavaObject::enumerate(oid=" << objectId
          << ", NEXT " << idNum << ")" << Debug::flush;
      *statep = INT_TO_JSVAL(idNum + 1);
      if (idNum >= NUM_PROPERTY_NAMES) {
        *statep = JSVAL_NULL;
#if GECKO_VERSION < 2000
	//TODO(jat): do we need to do this?
        *idp = JSVAL_NULL;
#endif //GECKO_VERSION
      } else {
        const char* propName = propertyNames[idNum];
        JSString* str = JS_NewStringCopyZ(ctx, propName);
        return JS_ValueToId(ctx, STRING_TO_JSVAL(str), idp);
      }
      break;
    }
    case JSENUMERATE_DESTROY:
      Debug::log(Debug::Spam) << "JavaObject::enumerate(oid=" << objectId
          << ", DESTROY)" << Debug::flush;
      *statep = JSVAL_NULL;
      break;
    default:
      Debug::log(Debug::Error) << "Unknown Enumerate op " <<
          static_cast<int>(op) << Debug::flush;
      return JS_FALSE;
  }
  return JS_TRUE;
}

void JavaObject::finalize(JSContext* ctx, JSObject* obj) {
  Debug::log(Debug::Spam) << "JavaObject::finalize obj=" << obj
      << " objId=" << JavaObject::getObjectId(ctx, obj) << Debug::flush;
  SessionData* data = JavaObject::getSessionData(ctx, obj);
  if (data) {
    int objectId = JavaObject::getObjectId(ctx, obj);
    data->freeJavaObject(objectId);
    JS_SetPrivate(ctx, obj, NULL);
  }
}

JSBool JavaObject::toString(JSContext* ctx, JSObject* obj, uintN argc,
    jsval* argv, jsval* rval) {
  SessionData* data = JavaObject::getSessionData(ctx, obj);
  if (!data) {
    *rval = JSVAL_VOID;
    return JS_TRUE;
  }
  int oid = getObjectId(ctx, obj);
  Debug::log(Debug::Spam) << "JavaObject::toString(id=" << oid << ")"
      << Debug::flush;
  Value javaThis;
  javaThis.setJavaObject(oid);
  // we ignore any supplied parameters
  return invokeJava(ctx, data, javaThis, InvokeMessage::TOSTRING_DISP_ID, 0,
      NULL, rval);
}

/**
 * Called when the JavaObject is invoked as a function.
 * We ignore the JSObject* argument, which is the 'this' context, which is
 * usually the window object. The JavaObject instance is in argv[-2].
 *
 * Returns a JS array, with the first element being a boolean indicating that
 * an exception occured, and the second element is either the return value or
 * the exception which was thrown.  In this case, we always return false and
 * raise the exception ourselves.
 */
JSBool JavaObject::call(JSContext* ctx, JSObject*, uintN argc, jsval* argv,
    jsval* rval) {
  // Get the JavaObject called as a function
  JSObject* obj = JSVAL_TO_OBJECT(argv[-2]);
  if (argc < 2 || !JSVAL_IS_INT(argv[0]) || !JSVAL_IS_OBJECT(argv[1])) {
    Debug::log(Debug::Error) << "JavaObject::call incorrect arguments" << Debug::flush;
    return JS_FALSE;
  }
  int dispId = JSVAL_TO_INT(argv[0]);
  if (Debug::level(Debug::Spam)) {
    Debug::DebugStream& dbg = Debug::log(Debug::Spam) << "JavaObject::call oid="
        << JavaObject::getObjectId(ctx, obj) << ",dispId=" << dispId << " (";
    for (unsigned i = 2; i < argc; ++i) {
      if (i > 2) {
        dbg << ", ";
      }
      dbg << dumpJsVal(ctx, argv[i]);
    }
    dbg << ")" << Debug::flush;
  }

  SessionData* data = JavaObject::getSessionData(ctx, obj);
  if (!data) {
    *rval = JSVAL_VOID;
    return JS_TRUE;
  }
  Debug::log(Debug::Spam) << "Data = " << data << Debug::flush;

  Value javaThis;
  if (!JSVAL_IS_NULL(argv[1])) {
    JSObject* thisObj = JSVAL_TO_OBJECT(argv[1]);
    if (isJavaObject(ctx, thisObj)) {
      javaThis.setJavaObject(getObjectId(ctx, thisObj));
    } else {
      data->makeValueFromJsval(javaThis, ctx, argv[1]);
    }
  } else {
    int oid = getObjectId(ctx, obj);
    javaThis.setJavaObject(oid);
  }
  return invokeJava(ctx, data, javaThis, dispId, argc - 2, &argv[2], rval);
}

#if GECKO_VERSION >= 2000
/**
 * Compatability wrapper for Gecko 2.0+
 */
JSBool JavaObject::toString20(JSContext* ctx, uintN argc, jsval* vp) {
  jsval rval = JSVAL_VOID;
  JSBool success;
  success = toString(ctx, JS_THIS_OBJECT(ctx, vp), argc, JS_ARGV(ctx, vp),
                       &rval);
  JS_SET_RVAL(cx, vp, rval);
  return success;
}

/**
 * Compatability wrapper method for Gecko 2.0+
 */
JSBool JavaObject::call20(JSContext* ctx, uintN argc, jsval* vp) {
  jsval rval = JSVAL_VOID;
  JSBool success;
  success = call(ctx, NULL, argc, JS_ARGV(ctx, vp), &rval);
  JS_SET_RVAL(ctx, vp, rval);
  return success;
}
#endif //GECKO_VERSION

/**
 * Calls a method on a Java object and returns a two-element JS array, with
 * the first element being a boolean flag indicating an exception was thrown,
 * and the second element is the actual return value or exception.
 */
JSBool JavaObject::invokeJava(JSContext* ctx, SessionData* data,
    const Value& javaThis, int dispId, int numArgs, const jsval* jsargs,
    jsval* rval) {
  HostChannel* channel = data->getHostChannel();
  SessionHandler* handler = data->getSessionHandler();
  scoped_array<Value> args(new Value[numArgs]);
  for (int i = 0; i < numArgs; ++i) {
    data->makeValueFromJsval(args[i], ctx, jsargs[i]);
  }

  bool isException = false;
  Value returnValue;
  if (!InvokeMessage::send(*channel, javaThis, dispId, numArgs, args.get())) {
    Debug::log(Debug::Debugging) << "JavaObject::call failed to send invoke message" << Debug::flush;
  } else {
    Debug::log(Debug::Spam) << " return from invoke" << Debug::flush;
    scoped_ptr<ReturnMessage> retMsg(channel->reactToMessagesWhileWaitingForReturn(handler));
    if (!retMsg.get()) {
      Debug::log(Debug::Debugging) << "JavaObject::call failed to get return value" << Debug::flush;
    } else {
      isException = retMsg->isException();
      returnValue = retMsg->getReturnValue();
    }
  }
  // Since we can set exceptions normally, we always return false to the
  // wrapper function and set the exception ourselves if one occurs.
  // TODO: cleanup exception case
  jsval retvalArray[] = {JSVAL_FALSE, JSVAL_VOID};
  JSObject* retval = JS_NewArrayObject(ctx, 2, retvalArray);
  *rval = OBJECT_TO_JSVAL(retval);
  jsval retJsVal;
  Debug::log(Debug::Spam) << "  result is " << returnValue << Debug::flush;
  data->makeJsvalFromValue(retJsVal, ctx, returnValue);
  if (isException) {
    JS_SetPendingException(ctx, retJsVal);
    return false;
  }
  if (!JS_SetElement(ctx, retval, 1, &retJsVal)) {
    Debug::log(Debug::Error) << "Error setting return value element in array"
        << Debug::flush;
    return false;
  }
  return true;
}
