// Copyright 2013 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/browser/renderer_host/websocket_dispatcher_host.h"

#include <string>
#include <vector>

#include "base/callback.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/websocket_host.h"
#include "content/common/websocket_messages.h"

namespace content {

namespace {

// Many methods defined in this file return a WebSocketHostState enum
// value. Make WebSocketHostState visible at file scope so it doesn't have to be
// fully-qualified every time.
typedef WebSocketDispatcherHost::WebSocketHostState WebSocketHostState;

}  // namespace

WebSocketDispatcherHost::WebSocketDispatcherHost(
    int process_id,
    const GetRequestContextCallback& get_context_callback)
    : BrowserMessageFilter(WebSocketMsgStart),
      process_id_(process_id),
      get_context_callback_(get_context_callback),
      websocket_host_factory_(
          base::Bind(&WebSocketDispatcherHost::CreateWebSocketHost,
                     base::Unretained(this))) {}

WebSocketDispatcherHost::WebSocketDispatcherHost(
    int process_id,
    const GetRequestContextCallback& get_context_callback,
    const WebSocketHostFactory& websocket_host_factory)
    : BrowserMessageFilter(WebSocketMsgStart),
      process_id_(process_id),
      get_context_callback_(get_context_callback),
      websocket_host_factory_(websocket_host_factory) {}

WebSocketHost* WebSocketDispatcherHost::CreateWebSocketHost(int routing_id) {
  return new WebSocketHost(routing_id, this, get_context_callback_.Run());
}

bool WebSocketDispatcherHost::OnMessageReceived(const IPC::Message& message) {
  switch (message.type()) {
    case WebSocketHostMsg_AddChannelRequest::ID:
    case WebSocketMsg_SendFrame::ID:
    case WebSocketMsg_FlowControl::ID:
    case WebSocketMsg_DropChannel::ID:
      break;

    default:
      // Every message that has not been handled by a previous filter passes
      // through here, so it is good to pass them on as efficiently as possible.
      return false;
  }

  int routing_id = message.routing_id();
  WebSocketHost* host = GetHost(routing_id);
  if (message.type() == WebSocketHostMsg_AddChannelRequest::ID) {
    if (host) {
      DVLOG(1) << "routing_id=" << routing_id << " already in use.";
      // The websocket multiplexing spec says to should drop the physical
      // connection in this case, but there isn't a real physical connection
      // to the renderer, and killing the renderer for this would seem to be a
      // little extreme. So for now just ignore the bogus request.
      return true;  // We handled the message (by ignoring it).
    }
    host = websocket_host_factory_.Run(routing_id);
    hosts_.insert(WebSocketHostTable::value_type(routing_id, host));
  }
  if (!host) {
    DVLOG(1) << "Received invalid routing ID " << routing_id
             << " from renderer.";
    return true;  // We handled the message (by ignoring it).
  }
  return host->OnMessageReceived(message);
}

bool WebSocketDispatcherHost::CanReadRawCookies() const {
  ChildProcessSecurityPolicyImpl* policy =
      ChildProcessSecurityPolicyImpl::GetInstance();
  return policy->CanReadRawCookies(process_id_);
}

WebSocketHost* WebSocketDispatcherHost::GetHost(int routing_id) const {
  WebSocketHostTable::const_iterator it = hosts_.find(routing_id);
  return it == hosts_.end() ? NULL : it->second;
}

WebSocketHostState WebSocketDispatcherHost::SendOrDrop(IPC::Message* message) {
  const uint32 message_type = message->type();
  const int32 message_routing_id = message->routing_id();
  if (!Send(message)) {
    message = NULL;
    DVLOG(1) << "Sending of message type " << message_type
             << " failed. Dropping channel.";
    DeleteWebSocketHost(message_routing_id);
    return WEBSOCKET_HOST_DELETED;
  }
  return WEBSOCKET_HOST_ALIVE;
}

WebSocketHostState WebSocketDispatcherHost::SendAddChannelResponse(
    int routing_id,
    bool fail,
    const std::string& selected_protocol,
    const std::string& extensions) {
  if (SendOrDrop(new WebSocketMsg_AddChannelResponse(
          routing_id, fail, selected_protocol, extensions)) ==
      WEBSOCKET_HOST_DELETED)
    return WEBSOCKET_HOST_DELETED;
  if (fail) {
    DeleteWebSocketHost(routing_id);
    return WEBSOCKET_HOST_DELETED;
  }
  return WEBSOCKET_HOST_ALIVE;
}

WebSocketHostState WebSocketDispatcherHost::SendFrame(
    int routing_id,
    bool fin,
    WebSocketMessageType type,
    const std::vector<char>& data) {
  return SendOrDrop(new WebSocketMsg_SendFrame(routing_id, fin, type, data));
}

WebSocketHostState WebSocketDispatcherHost::SendFlowControl(int routing_id,
                                                            int64 quota) {
  return SendOrDrop(new WebSocketMsg_FlowControl(routing_id, quota));
}

WebSocketHostState WebSocketDispatcherHost::NotifyClosingHandshake(
    int routing_id) {
  return SendOrDrop(new WebSocketMsg_NotifyClosing(routing_id));
}

WebSocketHostState WebSocketDispatcherHost::NotifyStartOpeningHandshake(
    int routing_id, const WebSocketHandshakeRequest& request) {
  return SendOrDrop(new WebSocketMsg_NotifyStartOpeningHandshake(
      routing_id, request));
}

WebSocketHostState WebSocketDispatcherHost::NotifyFinishOpeningHandshake(
    int routing_id, const WebSocketHandshakeResponse& response) {
  return SendOrDrop(new WebSocketMsg_NotifyFinishOpeningHandshake(
      routing_id, response));
}

WebSocketHostState WebSocketDispatcherHost::NotifyFailure(
    int routing_id,
    const std::string& message) {
  if (SendOrDrop(new WebSocketMsg_NotifyFailure(
          routing_id, message)) == WEBSOCKET_HOST_DELETED) {
    return WEBSOCKET_HOST_DELETED;
  }
  DeleteWebSocketHost(routing_id);
  return WEBSOCKET_HOST_DELETED;
}

WebSocketHostState WebSocketDispatcherHost::DoDropChannel(
    int routing_id,
    bool was_clean,
    uint16 code,
    const std::string& reason) {
  if (SendOrDrop(
          new WebSocketMsg_DropChannel(routing_id, was_clean, code, reason)) ==
      WEBSOCKET_HOST_DELETED)
    return WEBSOCKET_HOST_DELETED;
  DeleteWebSocketHost(routing_id);
  return WEBSOCKET_HOST_DELETED;
}

WebSocketDispatcherHost::~WebSocketDispatcherHost() {
  std::vector<WebSocketHost*> hosts;
  for (base::hash_map<int, WebSocketHost*>::const_iterator i = hosts_.begin();
       i != hosts_.end(); ++i) {
    // In order to avoid changing the container while iterating, we copy
    // the hosts.
    hosts.push_back(i->second);
  }

  for (size_t i = 0; i < hosts.size(); ++i) {
    // Note that some calls to GoAway could fail. In that case hosts[i] will be
    // deleted and removed from |hosts_| in |DoDropChannel|.
    hosts[i]->GoAway();
    hosts[i] = NULL;
  }

  STLDeleteContainerPairSecondPointers(hosts_.begin(), hosts_.end());
}

void WebSocketDispatcherHost::DeleteWebSocketHost(int routing_id) {
  WebSocketHostTable::iterator it = hosts_.find(routing_id);
  DCHECK(it != hosts_.end());
  delete it->second;
  hosts_.erase(it);
}

}  // namespace content
