/*
 * 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 "ExternalWrapper.h"

#include "nsIHttpProtocolHandler.h"
#include "nsISupports.h"
#include "nsNetCID.h"
#include "nsCOMPtr.h"
#include "nsMemory.h"
#include "nsServiceManagerUtils.h"
#include "nsIPromptService.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMLocation.h"
#include "nsXPCOMStrings.h"
#include "nsICategoryManager.h"
#include "nsIJSContextStack.h"
#include "nsIScriptContext.h"
#include "nsIScriptGlobalObject.h"
#include "nsPIDOMWindow.h"

#ifndef NS_IMPL_ISUPPORTS2_CI
#include "nsIClassInfoImpl.h" // 1.9 only
#endif

#include "LoadModuleMessage.h"
#include "ServerMethods.h"
#include "BrowserChannel.h"
#include "AllowedConnections.h"

NS_IMPL_ISUPPORTS2_CI(ExternalWrapper, IOOPHM, nsISecurityCheckedComponent)

ExternalWrapper::ExternalWrapper() {
  Debug::log(Debug::Debugging) << "ExternalWrapper::ExternalWrapper(this="
      << this << ")" << Debug::flush;
  preferences = new Preferences();
  windowWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
  if (!windowWatcher) {
    Debug::log(Debug::Warning) << "Can't get WindowWatcher service"
        << Debug::flush;
    return;
  }
}

ExternalWrapper::~ExternalWrapper() {
  Debug::log(Debug::Debugging) << "ExternalWrapper::~ExternalWrapper(this="
      << this << ")" << Debug::flush;
}

// define the CID for nsIHttpProtocolHandler
static NS_DEFINE_CID(kHttpHandlerCID, NS_HTTPPROTOCOLHANDLER_CID);

static nsresult getUserAgent(std::string& userAgent) {
  nsresult res;
  nsCOMPtr<nsIHttpProtocolHandler> http = do_GetService(kHttpHandlerCID, &res);
  if (NS_FAILED(res)) {
    return res;
  }
  nsCString userAgentStr;
  res = http->GetUserAgent(userAgentStr);
  if (NS_FAILED(res)) {
    return res;
  }
  userAgent.assign(userAgentStr.get());
  return NS_OK;
}

/**
 * Get JS window object.
 *
 * @param win output parameter to store the window object
 * @return true on success
 */
static bool getWindowObject(nsIDOMWindow** win) {
  // Get JSContext from stack.
  nsCOMPtr<nsIJSContextStack> stack =
      do_GetService("@mozilla.org/js/xpc/ContextStack;1");
  if (!stack) {
    Debug::log(Debug::Error) << "getWindowObject: no context stack"
        << Debug::flush;
    return false;
  }
  JSContext *cx;
  if (NS_FAILED(stack->Peek(&cx)) || !cx) {
    Debug::log(Debug::Error) << "getWindowObject: no context on stack"
        << Debug::flush;
    return false;
  }
  if (!(::JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS)) {
    Debug::log(Debug::Error)
        << "getWindowObject: context doesn't have nsISupports" << Debug::flush;
    return false;
  }

  nsCOMPtr<nsIScriptContext> scx =
    do_QueryInterface(static_cast<nsISupports *>
                                 (::JS_GetContextPrivate(cx)));
  if (!scx) {
    Debug::log(Debug::Error) << "getWindowObject: no script context"
        << Debug::flush;
    return false;
  }
  nsCOMPtr<nsIScriptGlobalObject> globalObj = scx->GetGlobalObject();
  if (!globalObj) {
    Debug::log(Debug::Error) << "getWindowObject: no global object"
        << Debug::flush;
    return false;
  }
  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(globalObj);
  if (!window) {
    Debug::log(Debug::Error) << "getWindowObject: window is null"
        << Debug::flush;
    return false;
  }
  NS_ADDREF(*win = window);
  return true;
}

/**
 * Get the URL of a window.
 *
 * @param win DOMWindowInternal instance
 * @param url output wide string for the URL
 * @return true if successful
 */
static bool getWindowUrl(nsIDOMWindowInternal* win, nsAString& url) {
  nsCOMPtr<nsIDOMLocation> loc;
  if (win->GetLocation(getter_AddRefs(loc)) != NS_OK) {
    Debug::log(Debug::Info) << "Unable to get location" << Debug::flush;
    return false;
  }
  if (loc->GetHref(url) != NS_OK) {
    Debug::log(Debug::Info) << "Unable to get URL" << Debug::flush;
    return false;
  }
  return true;
}

/**
 * Get the top-level window for a given window, and its URL.
 *
 * @param win window to start from
 * @param topWinRet output parameter to store top window
 * @param topUrl output parameter to store URL
 * @return true on success, false on error (already logged)
 */
static bool getTopWindow(nsIDOMWindow* win, nsIDOMWindowInternal** topWinRet,
    nsAString& topUrl) {
  nsCOMPtr<nsIDOMWindow> topWin;
  if (win->GetTop(getter_AddRefs(topWin)) != NS_OK) {
    Debug::log(Debug::Error) << "Unable to get top window" << Debug::flush;
    return false;
  }
  nsresult rv;
  nsCOMPtr<nsIDOMWindowInternal> topWinInt = do_QueryInterface(topWin, &rv);
  if (rv != NS_OK) {
    Debug::log(Debug::Error) << "Unable to QI DOMWindowInternal"
        << Debug::flush;
    return false;
  }
  if (!getWindowUrl(topWinInt, topUrl)) {
    Debug::log(Debug::Error) << "Unable to get url of top window"
        << Debug::flush;
    return false;
  }
  NS_ADDREF(*topWinRet = topWinInt);
  return true;
}

std::string ExternalWrapper::computeTabIdentity() {
  std::string returnVal;
  if (!windowWatcher) {
    return returnVal;
  }
  // The nsPIDOMWindow interface of our top-level window appears to be stable
  // across refreshes, so we will use that for our tab ID.
  nsCOMPtr<nsPIDOMWindow> privateWin = do_QueryInterface(topWindow);
  if (!privateWin) {
    return returnVal;
  }
  char buf[20]; // typically 8-16 hex digits plus 0x, not horrible if truncated
  snprintf(buf, sizeof(buf), "%p", privateWin.get());
  buf[19] = 0; // ensure null termination
  returnVal = buf;
  return returnVal;
}

// TODO(jat): remove suppliedWindow and update hosted.html API
NS_IMETHODIMP ExternalWrapper::Init(nsIDOMWindow* suppliedWindow,
    PRBool *_retval) {
  Debug::log(Debug::Debugging) << "Plugin initialized from hosted.html"
      << Debug::flush;
  *_retval = false;
  nsCOMPtr<nsIDOMWindow> computedWindow;
  if (getWindowObject(getter_AddRefs(computedWindow))) {
    Debug::log(Debug::Debugging) << " passed window=" << suppliedWindow
        << ", computed=" << computedWindow << Debug::flush;
    domWindow = computedWindow;
  } else {
    Debug::log(Debug::Warning) << " using supplied window object"
        << Debug::flush;
    // TODO(jat): remove this
    domWindow = suppliedWindow;
  }
  if (getTopWindow(domWindow, getter_AddRefs(topWindow), url)) {
    *_retval = true;
  }
  return NS_OK;
}

bool ExternalWrapper::askUserToAllow(const std::string& url) {
  nsCOMPtr<nsIPromptService> promptService = do_GetService(
      "@mozilla.org/embedcomp/prompt-service;1");
  if (!promptService) {
    return false;
  }
  NS_ConvertASCIItoUTF16 title("Allow GWT Developer Plugin Connection");
  NS_ConvertASCIItoUTF16 text("This web server is requesting a GWT "
      "developer plugin connection -- do you want to allow it?");
  NS_ConvertASCIItoUTF16 checkMsg("Remember this decision for this server "
      "(change in GWT Developer Plugin preferences)");
  PRBool remember = false;
  PRBool include = true;
  if (promptService->ConfirmCheck(domWindow.get(), title.get(), text.get(),
      checkMsg.get(), &remember, &include) != NS_OK) {
    return false;
  }
  if (remember) {
    preferences->addNewRule(AllowedConnections::getHostFromUrl(url), !include);
  }
  return include;
}

// TODO(jat): remove suppliedUrl and update hosted.html API
NS_IMETHODIMP ExternalWrapper::Connect(const nsACString& suppliedUrl,
                const nsACString& sessionKey, const nsACString& aAddr,
                const nsACString& aModuleName, const nsACString& hostedHtmlVersion,
                PRBool *_retval) {
  Debug::log(Debug::Info) << "Connect(url=" <<  url << ", sessionKey="
      << sessionKey << ", address=" << aAddr << ", module=" << aModuleName
      << ", hostedHtmlVersion=" << hostedHtmlVersion << Debug::flush;

  // TODO: string utilities?
  nsCString urlAutoStr;
  NS_UTF16ToCString(url, NS_CSTRING_ENCODING_UTF8, urlAutoStr);
  nsCString sessionKeyAutoStr(sessionKey);
  nsCString addrAutoStr(aAddr);
  nsCString moduleAutoStr(aModuleName);
  nsCString hostedHtmlVersionAutoStr(hostedHtmlVersion);
  std::string hostedUrl(addrAutoStr.get());
  std::string urlStr(urlAutoStr.get());

  bool allowed = false;
  if (!AllowedConnections::matchesRule(urlStr, &allowed)) {
    // If we didn't match an existing rule, prompt the user
    allowed = askUserToAllow(urlStr);
  }
  if (!allowed) {
    *_retval = false;
    return NS_OK;
  }

  size_t index = hostedUrl.find(':');
  if (index == std::string::npos) {
    *_retval = false;
    return NS_OK;
  }
  std::string hostPart = hostedUrl.substr(0, index);
  std::string portPart = hostedUrl.substr(index + 1);

  // TODO(jat): leaks HostChannel -- need to save it in a session object and
  // return that so the host page can call a disconnect method on it at unload
  // time or when it gets GC'd.
  HostChannel* channel = new HostChannel();

  Debug::log(Debug::Debugging) << "Connecting..." << Debug::flush;

  if (!channel->connectToHost(hostPart.c_str(),
      atoi(portPart.c_str()))) {
    *_retval = false;
    return NS_OK;
  }

  Debug::log(Debug::Debugging) << "...Connected" << Debug::flush;
  sessionHandler.reset(new FFSessionHandler(channel/*, ctx*/));

  std::string hostedHtmlVersionStr(hostedHtmlVersionAutoStr.get());
  if (!channel->init(sessionHandler.get(), BROWSERCHANNEL_PROTOCOL_VERSION,
      BROWSERCHANNEL_PROTOCOL_VERSION, hostedHtmlVersionStr)) {
    *_retval = false;
    return NS_OK;
  }

  std::string moduleName(moduleAutoStr.get());
  std::string userAgent;

  // get the user agent
  nsresult res = getUserAgent(userAgent);
  if (NS_FAILED(res)) {
    return res;
  }

  std::string tabKeyStr = computeTabIdentity();
  std::string sessionKeyStr(sessionKeyAutoStr.get());

  LoadModuleMessage::send(*channel, urlStr, tabKeyStr, sessionKeyStr,
      moduleName, userAgent, sessionHandler.get());

  // TODO: return session object?
  *_retval = true;
  return NS_OK;
}

// nsISecurityCheckedComponent
static char* cloneAllAccess() {
  static const char allAccess[] = "allAccess";
  return static_cast<char*>(nsMemory::Clone(allAccess, sizeof(allAccess)));
}

static bool strEquals(const PRUnichar* utf16, const char* ascii) {
  nsCString utf8;
  NS_UTF16ToCString(nsDependentString(utf16), NS_CSTRING_ENCODING_UTF8, utf8);
  return strcmp(ascii, utf8.get()) == 0;
}

NS_IMETHODIMP ExternalWrapper::CanCreateWrapper(const nsIID * iid,
    char **_retval) {
  Debug::log(Debug::Spam) << "ExternalWrapper::CanCreateWrapper"
      << Debug::flush;
  *_retval = cloneAllAccess();
  return NS_OK;
}

NS_IMETHODIMP ExternalWrapper::CanCallMethod(const nsIID * iid,
    const PRUnichar *methodName, char **_retval) {
  Debug::log(Debug::Spam) << "ExternalWrapper::CanCallMethod" << Debug::flush;
  if (strEquals(methodName, "connect") || strEquals(methodName, "init")) {
    *_retval = cloneAllAccess();
  } else {
    *_retval = nsnull;
  }
  return NS_OK;
}

NS_IMETHODIMP ExternalWrapper::CanGetProperty(const nsIID * iid,
    const PRUnichar *propertyName, char **_retval) {
  Debug::log(Debug::Spam) << "ExternalWrapper::CanGetProperty" << Debug::flush;
  *_retval = nsnull;
  return NS_OK;
}
NS_IMETHODIMP ExternalWrapper::CanSetProperty(const nsIID * iid,
    const PRUnichar *propertyName, char **_retval) {
  Debug::log(Debug::Spam) << "ExternalWrapper::CanSetProperty" << Debug::flush;
  *_retval = nsnull;
  return NS_OK;
}
