// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/worker/websharedworkerclient_proxy.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "content/child/fileapi/file_system_dispatcher.h"
#include "content/child/fileapi/webfilesystem_callback_adapters.h"
#include "content/child/quota_dispatcher.h"
#include "content/child/webmessageportchannel_impl.h"
#include "content/common/worker_messages.h"
#include "content/public/common/content_switches.h"
#include "content/worker/shared_worker_devtools_agent.h"
#include "content/worker/websharedworker_stub.h"
#include "content/worker/worker_thread.h"
#include "content/worker/worker_webapplicationcachehost_impl.h"
#include "ipc/ipc_logging.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFileSystemCallbacks.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebSecurityOrigin.h"

using WebKit::WebApplicationCacheHost;
using WebKit::WebFrame;
using WebKit::WebMessagePortChannel;
using WebKit::WebMessagePortChannelArray;
using WebKit::WebSecurityOrigin;
using WebKit::WebString;
using WebKit::WebWorker;
using WebKit::WebSharedWorkerClient;

namespace content {

// How long to wait for worker to finish after it's been told to terminate.
#define kMaxTimeForRunawayWorkerSeconds 3

WebSharedWorkerClientProxy::WebSharedWorkerClientProxy(
    int route_id, WebSharedWorkerStub* stub)
    : route_id_(route_id),
      appcache_host_id_(0),
      stub_(stub),
      weak_factory_(this),
      devtools_agent_(NULL) {
}

WebSharedWorkerClientProxy::~WebSharedWorkerClientProxy() {
}

void WebSharedWorkerClientProxy::postMessageToWorkerObject(
    const WebString& message,
    const WebMessagePortChannelArray& channels) {
  std::vector<int> message_port_ids(channels.size());
  std::vector<int> routing_ids(channels.size());
  for (size_t i = 0; i < channels.size(); ++i) {
    WebMessagePortChannelImpl* webchannel =
        static_cast<WebMessagePortChannelImpl*>(channels[i]);
    message_port_ids[i] = webchannel->message_port_id();
    webchannel->QueueMessages();
    DCHECK(message_port_ids[i] != MSG_ROUTING_NONE);
    routing_ids[i] = MSG_ROUTING_NONE;
  }

  Send(new WorkerMsg_PostMessage(
      route_id_, message, message_port_ids, routing_ids));
}

void WebSharedWorkerClientProxy::postExceptionToWorkerObject(
    const WebString& error_message,
    int line_number,
    const WebString& source_url) {
  Send(new WorkerHostMsg_PostExceptionToWorkerObject(
      route_id_, error_message, line_number, source_url));
}

void WebSharedWorkerClientProxy::postConsoleMessageToWorkerObject(
    int source,
    int type,
    int level,
    const WebString& message,
    int line_number,
    const WebString& source_url) {
  WorkerHostMsg_PostConsoleMessageToWorkerObject_Params params;
  params.source_identifier = source;
  params.message_type = type;
  params.message_level = level;
  params.message = message;
  params.line_number = line_number;
  params.source_url = source_url;
  Send(new WorkerHostMsg_PostConsoleMessageToWorkerObject(route_id_, params));
}

void WebSharedWorkerClientProxy::confirmMessageFromWorkerObject(
    bool has_pending_activity) {
  Send(new WorkerHostMsg_ConfirmMessageFromWorkerObject(
      route_id_, has_pending_activity));
}

void WebSharedWorkerClientProxy::reportPendingActivity(
    bool has_pending_activity) {
  Send(new WorkerHostMsg_ReportPendingActivity(
      route_id_, has_pending_activity));
}

void WebSharedWorkerClientProxy::workerContextClosed() {
  Send(new WorkerHostMsg_WorkerContextClosed(route_id_));
}

void WebSharedWorkerClientProxy::workerContextDestroyed() {
  Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_));
  // Tell the stub that the worker has shutdown - frees this object.
  if (stub_)
    stub_->Shutdown();
}

WebKit::WebNotificationPresenter*
WebSharedWorkerClientProxy::notificationPresenter() {
  // TODO(johnnyg): Notifications are not yet hooked up to workers.
  // Coming soon.
  NOTREACHED();
  return NULL;
}

WebApplicationCacheHost* WebSharedWorkerClientProxy::createApplicationCacheHost(
    WebKit::WebApplicationCacheHostClient* client) {
  WorkerWebApplicationCacheHostImpl* host =
      new WorkerWebApplicationCacheHostImpl(stub_->appcache_init_info(),
                                            client);
  // Remember the id of the instance we create so we have access to that
  // value when creating nested dedicated workers in createWorker.
  appcache_host_id_ = host->host_id();
  return host;
}

// TODO(abarth): Security checks should use WebDocument or WebSecurityOrigin,
// not WebFrame as the context object because WebFrames can contain different
// WebDocuments at different times.
bool WebSharedWorkerClientProxy::allowDatabase(WebFrame* frame,
                                         const WebString& name,
                                         const WebString& display_name,
                                         unsigned long estimated_size) {
  WebSecurityOrigin origin = frame->document().securityOrigin();
  if (origin.isUnique())
    return false;

  bool result = false;
  Send(new WorkerProcessHostMsg_AllowDatabase(
      route_id_, GURL(origin.toString().utf8()), name, display_name,
      estimated_size, &result));
  return result;
}

bool WebSharedWorkerClientProxy::allowFileSystem() {
  bool result = false;
  Send(new WorkerProcessHostMsg_AllowFileSystem(
      route_id_, stub_->url().GetOrigin(), &result));
  return result;
}

void WebSharedWorkerClientProxy::openFileSystem(
    WebKit::WebFileSystemType type,
    long long size,
    bool create,
    WebKit::WebFileSystemCallbacks* callbacks) {
  ChildThread::current()->file_system_dispatcher()->OpenFileSystem(
      stub_->url().GetOrigin(), static_cast<fileapi::FileSystemType>(type),
      size, create,
      base::Bind(&OpenFileSystemCallbackAdapter, callbacks),
      base::Bind(&FileStatusCallbackAdapter, callbacks));
}

bool WebSharedWorkerClientProxy::allowIndexedDB(const WebKit::WebString& name) {
  bool result = false;
  Send(new WorkerProcessHostMsg_AllowIndexedDB(
      route_id_, stub_->url().GetOrigin(), name, &result));
  return result;
}

void WebSharedWorkerClientProxy::queryUsageAndQuota(
    WebKit::WebStorageQuotaType type,
    WebKit::WebStorageQuotaCallbacks* callbacks) {
  ChildThread::current()->quota_dispatcher()->QueryStorageUsageAndQuota(
      stub_->url().GetOrigin(), static_cast<quota::StorageType>(type),
      QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
}

void WebSharedWorkerClientProxy::dispatchDevToolsMessage(
    const WebString& message) {
  if (devtools_agent_)
    devtools_agent_->SendDevToolsMessage(message);
}

void WebSharedWorkerClientProxy::saveDevToolsAgentState(
    const WebKit::WebString& state) {
  if (devtools_agent_)
    devtools_agent_->SaveDevToolsAgentState(state);
}

bool WebSharedWorkerClientProxy::Send(IPC::Message* message) {
  return WorkerThread::current()->Send(message);
}

void WebSharedWorkerClientProxy::EnsureWorkerContextTerminates() {
  // This shuts down the process cleanly from the perspective of the browser
  // process, and avoids the crashed worker infobar from appearing to the new
  // page. It's ok to post several of theese, because the first executed task
  // will exit the message loop and subsequent ones won't be executed.
  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&WebSharedWorkerClientProxy::workerContextDestroyed,
                 weak_factory_.GetWeakPtr()),
      base::TimeDelta::FromSeconds(kMaxTimeForRunawayWorkerSeconds));
}

}  // namespace content
