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

#include "jsapi.h"
#include "nsCOMPtr.h"
#include "nsStringAPI.h"
#include "nsIJSContextStack.h"
#include "nsIPrincipal.h"
#include "nsServiceManagerUtils.h"

static JSContext* getJSContext() {
  // Get JSContext from stack.
  nsCOMPtr<nsIJSContextStack> stack =
      do_GetService("@mozilla.org/js/xpc/ContextStack;1");
  if (!stack) {
    return NULL;
  }

  JSContext *cx;
  if (NS_FAILED(stack->Peek(&cx))) {
    return NULL;
  }

  if (cx == nsnull) {
    // TODO(jat): figure out why this can be null at plugin unload time
    Debug::log(Debug::Error) << "GWT DMP: Null JS context" << Debug::flush;
  }

  return cx;
}

FFSessionHandler::FFSessionHandler(HostChannel* channel)
    : SessionData(channel, this, getJSContext()), jsObjectId(0),
    jsObjectsById(NULL), stringObjectClass(NULL) {
  // TODO(jat): is there a way to avoid calling this twice, without keeping
  // JSContext in an instance field?
  JSContext* ctx = getJSContext();
  if (!JS_AddNamedRoot(ctx, &jsObjectsById, "jsObjectsById")) {
    Debug::log(Debug::Error) << "Error rooting jsObjectsById" << Debug::flush;
  }
  jsObjectsById = JS_NewArrayObject(ctx, 0, NULL);
  if (!jsObjectsById) {
    Debug::log(Debug::Error) << "Error rooting jsObjectsById" << Debug::flush;
  }
  if (!JS_AddNamedRoot(ctx, &toStringTearOff, "toStringTearOff")) {
    Debug::log(Debug::Error) << "Error rooting toStringTearOff" << Debug::flush;
  }
  getStringObjectClass(ctx);
  getToStringTearOff(ctx);
}

void FFSessionHandler::getStringObjectClass(JSContext* ctx) {
  jsval str = JS_GetEmptyStringValue(ctx);
  JSObject* obj = 0;
  if (!JS_ValueToObject(ctx, str, &obj)) {
    return;
  }
  if (!obj) {
    return;
  }
  stringObjectClass = JS_GET_CLASS(ctx, obj);
}

void FFSessionHandler::getToStringTearOff(JSContext* ctx) {
  jsval funcVal;

  Debug::log(Debug::Debugging) << "Getting function \"__gwt_makeTearOff\""
        << Debug::flush;

  if (!JS_GetProperty(ctx, global, "__gwt_makeTearOff", &funcVal)
      || funcVal == JSVAL_VOID) {
    Debug::log(Debug::Error) << "Could not get function \"__gwt_makeTearOff\""
        << Debug::flush;
    return;
  }
  jsval jsargs[3] = {
    JSVAL_NULL,                                     // no proxy
    INT_TO_JSVAL(InvokeMessage::TOSTRING_DISP_ID),  // dispId
    JSVAL_ZERO                                      // arg count is zero
  };
  if (!JS_CallFunctionValue(ctx, global, funcVal, 3, jsargs, &toStringTearOff)) {
    jsval exc;
    if (JS_GetPendingException(ctx, &exc)) {
      Debug::log(Debug::Error)
          << "__gwt_makeTearOff(null,0,0) threw exception "
          << dumpJsVal(ctx, exc) << Debug::flush;
    } else {
      Debug::log(Debug::Error) << "Error creating toString tear-off"
          << Debug::flush;
    }
    // TODO(jat): show some crash page and die
  }
}

FFSessionHandler::~FFSessionHandler(void) {
  Debug::log(Debug::Debugging) << "FFSessionHandler::~FFSessionHandler" << Debug::flush;
  disconnect();
  if (runtime) {
    JS_RemoveRootRT(runtime, &jsObjectsById);
    jsObjectsById = NULL;
    JS_RemoveRootRT(runtime, &toStringTearOff);
    runtime = NULL;
  }
}

void FFSessionHandler::freeValue(HostChannel& channel, int idCount, const int* ids) {
  Debug::DebugStream& dbg = Debug::log(Debug::Spam)
      << "FFSessionHandler::freeValue [ ";
  JSContext* ctx = getJSContext();

  for (int i = 0; i < idCount; ++i) {
    int objId = ids[i];
    dbg << objId << " ";
    jsval toRemove;
    if (JS_GetElement(ctx, jsObjectsById, objId, &toRemove) && JSVAL_IS_OBJECT(toRemove)) {
      jsIdsByObject.erase(identityFromObject(JSVAL_TO_OBJECT(toRemove)));
      JS_DeleteElement(ctx, jsObjectsById, objId);
    } else {
      Debug::log(Debug::Error) << "Error deleting js objId=" << objId << Debug::flush;
    }
  }

  dbg << "]" << Debug::flush;
}

void FFSessionHandler::loadJsni(HostChannel& channel, const std::string& js) {
  Debug::log(Debug::Spam) << "FFSessionHandler::loadJsni " << js << "(EOM)" << Debug::flush;
  JSContext* ctx = getJSContext();
  if (!JSRunner::eval(ctx, global, js)) {
    Debug::log(Debug::Error) << "Error executing script" << Debug::flush;
  }
}

void FFSessionHandler::sendFreeValues(HostChannel& channel) {
  unsigned n = javaObjectsToFree.size();
  if (n) {
    scoped_array<int> ids(new int[n]);
    int i = 0;
    for (std::set<int>::iterator it = javaObjectsToFree.begin();
        it != javaObjectsToFree.end(); ++it) {
      ids[i++] = *it;
    }
    if (ServerMethods::freeJava(channel, this, n, ids.get())) {
      javaObjectsToFree.clear();
    }
  }
}

void FFSessionHandler::fatalError(HostChannel& channel,
    const std::string& message) {
  // TODO(jat): implement
}

bool FFSessionHandler::invoke(HostChannel& channel, const Value& thisObj, const std::string& methodName,
    int numArgs, const Value* const args, Value* returnValue) {
  Debug::log(Debug::Spam) << "FFSessionHandler::invoke " << thisObj.toString()
      << "::" << methodName << Debug::flush;
  JSContext* ctx = getJSContext();

  // Used to root JSthis and args while making the JS call
  // TODO(jat): keep one object and just keep a "stack pointer" into that
  // object on the native stack so we don't keep allocating/rooting/freeing
  // an object
  RootedObject argsRoot(ctx, "FFSessionhandler::invoke");
  argsRoot = JS_NewArrayObject(ctx, 0, NULL);
  if (!JS_SetArrayLength(ctx, argsRoot.get(), numArgs + 1)) {
    Debug::log(Debug::Error)
        << "FFSessionhandler::invoke - could not set argsRoot length"
        << Debug::flush;
    return true;
  }

  jsval jsThis;
  if (thisObj.isNull()) {
    jsThis = OBJECT_TO_JSVAL(global);
    Debug::log(Debug::Spam) << "  using global object for this" << Debug::flush;
  } else {
    makeJsvalFromValue(jsThis, ctx, thisObj);
    if (Debug::level(Debug::Spam)) {
      Debug::log(Debug::Spam) << "  obj=" << dumpJsVal(ctx, jsThis)
          << Debug::flush;
    }
  }
  if (!JS_SetElement(ctx, argsRoot.get(), 0, &jsThis)) {
    Debug::log(Debug::Error)
        << "FFSessionhandler::invoke - could not set argsRoot[0] to this"
        << Debug::flush;
    return true;
  }

  jsval funcVal;
  // TODO: handle non-ASCII method names
  if (!JS_GetProperty(ctx, global, methodName.c_str(), &funcVal)
      || funcVal == JSVAL_VOID) {
    Debug::log(Debug::Error) << "Could not get function " << methodName
        << Debug::flush;
    return true;
  }

  scoped_array<jsval> jsargs(new jsval[numArgs]);
  for (int i = 0; i < numArgs; ++i) {
    makeJsvalFromValue(jsargs[i], ctx, args[i]);
    if (Debug::level(Debug::Spam)) {
      Debug::log(Debug::Spam) << "  arg[" << i << "] = " << dumpJsVal(ctx,
          jsargs[i]) << Debug::flush;
    }
    if (!JS_SetElement(ctx, argsRoot.get(), i + 1, &jsargs[i])) {
      Debug::log(Debug::Error)
          << "FFSessionhandler::invoke - could not set args[" << (i + 1) << "]"
          << Debug::flush;
      return true;
    }
  }

  if (JS_IsExceptionPending(ctx)) {
    JS_ClearPendingException(ctx);
  }

  jsval rval;
  JSBool ok = JS_CallFunctionValue(ctx, JSVAL_TO_OBJECT(jsThis), funcVal,
      numArgs, jsargs.get(), &rval);

  if (!ok) {
    if (JS_GetPendingException(ctx, &rval)) {
      makeValueFromJsval(*returnValue, ctx, rval);
      Debug::log(Debug::Debugging) << "FFSessionHandler::invoke "
          << thisObj.toString() << "::" << methodName << " threw exception "
          << dumpJsVal(ctx, rval) << Debug::flush;
    } else {
      Debug::log(Debug::Error) << "Non-exception failure invoking "
          << methodName << Debug::flush;
      returnValue->setUndefined();
    }
  } else {
    makeValueFromJsval(*returnValue, ctx, rval);
  }
  Debug::log(Debug::Spam) << "  return= " << *returnValue << Debug::flush;
  return !ok;
}

/**
 * Invoke a plugin-provided method with the given args.  As above, this method does not own
 * any of its args.
 *
 * Returns true if an exception occurred.
 */
bool FFSessionHandler::invokeSpecial(HostChannel& channel, SpecialMethodId method, int numArgs,
    const Value* const args, Value* returnValue)  {
  Debug::log(Debug::Spam) << "FFSessionHandler::invokeSpecial" << Debug::flush;
  return false;
}

/**
 * Convert UTF16 string to UTF8-encoded std::string.
 *
 * This is implemented here because the Mozilla libraries mangle certain UTF8
 * strings.
 *
 * @return UTF8-encoded string.
 */
static std::string utf8String(const jschar* str, unsigned len) {
  std::string utf8str;
  while (len-- > 0) {
    unsigned ch = *str++;
    // check for paired surrogates first, leave unpaired surrogates as-is
    if (ch >= 0xD800 && ch < 0xDC00 && len > 0 && *str >= 0xDC00 && *str < 0xE000) {
      ch = ((ch & 1023) << 10) + (*str++ & 1023) + 0x10000;
      len--;
    }
    if (ch < 0x80) {          // U+0000 - U+007F as 0xxxxxxx
      utf8str.append(1, ch);
    } else if (ch < 0x800) {  // U+0080 - U+07FF as 110xxxxx 10xxxxxx
      utf8str.append(1, 0xC0 + ((ch >> 6) & 31));
      utf8str.append(1, 0x80 + (ch & 63));
    } else if (ch < 0x10000) { // U+0800 - U+FFFF as 1110xxxx 10xxxxxx 10xxxxxx
      utf8str.append(1, 0xE0 + ((ch >> 12) & 15));
      utf8str.append(1, 0x80 + ((ch >> 6) & 63));
      utf8str.append(1, 0x80 + (ch & 63));
    } else {  // rest as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
      utf8str.append(1, 0xF0 + ((ch >> 18) & 7));
      utf8str.append(1, 0x80 + ((ch >> 12) & 63));
      utf8str.append(1, 0x80 + ((ch >> 6) & 63));
      utf8str.append(1, 0x80 + (ch & 63));
    }
  }
  return utf8str;
}

/**
 * Creates a JSString from a UTF8-encoded std::string.
 *
 * This is implemented here because the Mozilla libraries mangle certain UTF8
 * strings.
 *
 * @return the JSString object, which owns its memory buffer.
 */
static JSString* stringUtf8(JSContext* ctx, const std::string& utf8str) {
  unsigned len = 0;
  for (unsigned i = 0; i < utf8str.length(); ++i) {
    char ch = utf8str[i];
    switch (ch & 0xF8) {
      // continuation & invalid chars
      default:
      // ASCII characters
      case 0x00: case 0x08: case 0x10: case 0x18:
      case 0x20: case 0x28: case 0x30: case 0x38:
      case 0x40: case 0x48: case 0x50: case 0x58:
      case 0x60: case 0x68: case 0x70: case 0x78:
      // 2-byte UTF8 characters
      case 0xC0: case 0xC8: case 0xD0: case 0xD8:
      // 3-byte UTF8 characters
      case 0xE0: case 0xE8:
        ++len;
        break;
      case 0xF0:
        len += 2;
        break;
    }
  }
  // Account for null terminator even if it isn't included in the string length
  // Note that buf becomes owned by the JSString and must not be freed here.
  jschar* buf = static_cast<jschar*>(JS_malloc(ctx, (len + 1) * sizeof(jschar)));
  if (!buf) {
    return NULL;
  }
  jschar* p = buf;
  unsigned codePoint;
  int charsLeft = -1;
  for (unsigned i = 0; i < utf8str.length(); ++i) {
    char ch = utf8str[i];
    if (charsLeft >= 0) {
      if ((ch & 0xC0) != 0x80) {
        // invalid, missing continuation character
        *p++ = static_cast<jschar>(0xFFFD);
        charsLeft = -1;
      } else {
        codePoint = (codePoint << 6) | (ch & 63);
        if (!--charsLeft) {
          if (codePoint >= 0x10000) {
            codePoint -= 0x10000;
            *p++ = static_cast<jschar>(0xD800 + ((codePoint >> 10) & 1023));
            *p++ = static_cast<jschar>(0xDC00 + (codePoint & 1023));
          } else {
            *p++ = static_cast<jschar>(codePoint);
          }
          charsLeft = -1;
        }
      }
      continue;
    }
    // Look at the top 5 bits to determine how many bytes are in this character.
    switch (ch & 0xF8) {
      default: // skip invalid and continuation chars
        break;
      case 0x00: case 0x08: case 0x10: case 0x18:
      case 0x20: case 0x28: case 0x30: case 0x38:
      case 0x40: case 0x48: case 0x50: case 0x58:
      case 0x60: case 0x68: case 0x70: case 0x78:
        *p++ = static_cast<jschar>(ch);
        break;
      case 0xC0: case 0xC8: case 0xD0: case 0xD8:
        charsLeft = 1;
        codePoint = ch & 31;
        break;
      case 0xE0: case 0xE8:
        charsLeft = 2;
        codePoint = ch & 15;
        break;
      case 0xF0:
        charsLeft = 3;
        codePoint = ch & 7;
        break;
    }
  }
  // null terminator, apparently some code expects a terminator even though
  // the strings are counted.  Note that this null word should not be included
  // in the length, and that the buffer becomes owned by the JSString object.
  *p = 0;
  return JS_NewUCString(ctx, buf, p - buf);
}

void FFSessionHandler::makeValueFromJsval(Value& retVal, JSContext* ctx,
    const jsval& value) {
  if (JSVAL_IS_VOID(value)) {
    retVal.setUndefined();
  } else if (JSVAL_IS_NULL(value)) {
    retVal.setNull();
  } else if (JSVAL_IS_INT(value)) {
    retVal.setInt(JSVAL_TO_INT(value));
  } else if (JSVAL_IS_BOOLEAN(value)) {
    retVal.setBoolean(JSVAL_TO_BOOLEAN(value));
  } else if (JSVAL_IS_STRING(value)) {
    JSString* str = JSVAL_TO_STRING(value);
    retVal.setString(utf8String(JS_GetStringChars(str),
        JS_GetStringLength(str)));
  } else if (JSVAL_IS_DOUBLE(value)) {
    retVal.setDouble(*JSVAL_TO_DOUBLE(value));
  } else if (JSVAL_IS_OBJECT(value)) {
    JSObject* obj = JSVAL_TO_OBJECT(value);
    if (JavaObject::isJavaObject(ctx, obj)) {
      retVal.setJavaObject(JavaObject::getObjectId(ctx, obj));
    } else if (JS_GET_CLASS(ctx, obj) == stringObjectClass) {
      // JS String wrapper object, treat as a string primitive
      JSString* str = JS_ValueToString(ctx, value);
      retVal.setString(utf8String(JS_GetStringChars(str),
          JS_GetStringLength(str)));
      // str will be garbage-collected, does not need to be freed
    } else {
      // It's a plain-old JavaScript Object
      void* objKey = identityFromObject(obj);
      std::map<void*, int>::iterator it = jsIdsByObject.find(objKey);
      if (it != jsIdsByObject.end()) {
        retVal.setJsObjectId(it->second);
      } else {
        // Allocate a new id
        int objId = ++jsObjectId;
        JS_SetElement(ctx, jsObjectsById, objId, const_cast<jsval*>(&value));
        jsIdsByObject[objKey] = objId;
        retVal.setJsObjectId(objId);
      }
    }
  } else {
    Debug::log(Debug::Error) << "Unhandled jsval type " << Debug::flush;
    retVal.setString("Unhandled jsval type");
  }
}

void FFSessionHandler::makeJsvalFromValue(jsval& retVal, JSContext* ctx,
    const Value& value) {
  switch (value.getType()) {
    case Value::NULL_TYPE:
      retVal = JSVAL_NULL;
      break;
    case Value::BOOLEAN:
      retVal = BOOLEAN_TO_JSVAL(value.getBoolean());
      break;
    case Value::BYTE:
      retVal = INT_TO_JSVAL((int) value.getByte());
      break;
    case Value::CHAR:
      retVal = INT_TO_JSVAL((int) value.getChar());
      break;
    case Value::SHORT:
      retVal = INT_TO_JSVAL((int) value.getShort());
      break;
    case Value::INT: {
      int intValue = value.getInt();
      if (INT_FITS_IN_JSVAL(intValue)) {
        retVal = INT_TO_JSVAL(intValue);
      } else {
        JS_NewNumberValue(ctx, (jsdouble) intValue, &retVal);
      }
      break;
    }
    // TODO(jat): do we still need long support in the wire format and Value?
//    case Value::LONG:
//      retVal = value.getLong();
//      break;
    case Value::FLOAT:
      JS_NewNumberValue(ctx, (jsdouble) value.getFloat(), &retVal);
      break;
    case Value::DOUBLE:
      JS_NewNumberValue(ctx, (jsdouble) value.getDouble(), &retVal);
      break;
    case Value::STRING:
      {
        JSString* str = stringUtf8(ctx, value.getString());
        retVal = STRING_TO_JSVAL(str);
      }
      break;
    case Value::JAVA_OBJECT:
      {
        int javaId = value.getJavaObjectId();
        std::map<int, JSObject*>::iterator i = javaObjectsById.find(javaId);
        if (i == javaObjectsById.end()) {
          JSObject* obj = JavaObject::construct(ctx, this, javaId);
          javaObjectsById[javaId] = obj;
          // We may have previously released the proxy for the same object id,
          // but have not yet sent a free message back to the server.
          javaObjectsToFree.erase(javaId);
          retVal = OBJECT_TO_JSVAL(obj);
        } else {
          retVal = OBJECT_TO_JSVAL(i->second);
        }
      }
      break;
    case Value::JS_OBJECT:
      {
        int jsId = value.getJsObjectId();
        if (!JS_GetElement(ctx, jsObjectsById, jsId, &retVal)) {
          Debug::log(Debug::Error) << "Error getting jsObject with id " << jsId << Debug::flush;
        }
        if (!JSVAL_IS_OBJECT(retVal)) {
          Debug::log(Debug::Error) << "Missing jsObject with id " << jsId << Debug::flush;
        }
      }
      break;
    case Value::UNDEFINED:
      retVal = JSVAL_VOID;
      break;
    default:
      Debug::log(Debug::Error) << "Unknown Value type " << value.toString() << Debug::flush;
  }
}

void FFSessionHandler::freeJavaObject(int objectId) {
  if (!javaObjectsById.erase(objectId)) {
    Debug::log(Debug::Error) << "Trying to free unknown JavaObject: " << objectId << Debug::flush;
    return;
  }
  javaObjectsToFree.insert(objectId);
}

void FFSessionHandler::disconnect() {
  Debug::log(Debug::Debugging) << "FFSessionHandler::disconnect" << Debug::flush;
  JSContext* ctx = getJSContext();
  bool freeCtx = false;
  if (!ctx) {
    Debug::log(Debug::Debugging) << "  creating temporary context"
        << Debug::flush;
    freeCtx = true;
    ctx = JS_NewContext(runtime, 8192);
    if (ctx) {
      JS_SetOptions(ctx, JSOPTION_VAROBJFIX);
#ifdef JSVERSION_LATEST
      JS_SetVersion(ctx, JSVERSION_LATEST);
#endif
    }
  }
  if (ctx) {
    JS_BeginRequest(ctx);
    for (std::map<int, JSObject*>::iterator it = javaObjectsById.begin();
        it != javaObjectsById.end(); ++it) {
      int javaId = it->first;
      JSObject* obj = it->second;
      if (JavaObject::isJavaObject(ctx, obj)) {
        // clear the SessionData pointer -- JavaObject knows it is
        // disconnected if this is null
        JS_SetPrivate(ctx, obj, NULL);
        javaObjectsToFree.erase(javaId);
      }
    }
    JS_EndRequest(ctx);
    if (freeCtx) {
      JS_DestroyContext(ctx);
    }
  } else {
    Debug::log(Debug::Warning)
        << "FFSessionHandler::disconnect - no context available"
        << Debug::flush;
  }
  HostChannel* channel = getHostChannel();
  if (channel->isConnected()) {
    channel->disconnectFromHost();
  }
}

void* FFSessionHandler::identityFromObject(JSObject* obj) {
  JSContext* ctx = getJSContext();
  jsval rval;
  void* returnValue = obj;
  if (JS_GetProperty(ctx, obj, "wrappedJSObject", &rval)
      && JSVAL_IS_OBJECT(rval)) {
    returnValue = JSVAL_TO_OBJECT(rval);
    Debug::log(Debug::Info) << "identityFromObject mapped " << obj << " to "
        << returnValue << Debug::flush;
  }
  return returnValue;
}
