// Copyright 2014 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 "net/socket/websocket_endpoint_lock_manager.h"

#include <utility>

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"

namespace net {

namespace {

// This delay prevents DoS attacks.
// TODO(ricea): Replace this with randomised truncated exponential backoff.
// See crbug.com/377613.
const int kUnlockDelayInMs = 10;

}  // namespace

WebSocketEndpointLockManager::Waiter::~Waiter() {
  if (next()) {
    DCHECK(previous());
    RemoveFromList();
  }
}

WebSocketEndpointLockManager* WebSocketEndpointLockManager::GetInstance() {
  return Singleton<WebSocketEndpointLockManager>::get();
}

int WebSocketEndpointLockManager::LockEndpoint(const IPEndPoint& endpoint,
                                               Waiter* waiter) {
  LockInfoMap::value_type insert_value(endpoint, LockInfo());
  std::pair<LockInfoMap::iterator, bool> rv =
      lock_info_map_.insert(insert_value);
  LockInfo& lock_info_in_map = rv.first->second;
  if (rv.second) {
    DVLOG(3) << "Locking endpoint " << endpoint.ToString();
    lock_info_in_map.queue.reset(new LockInfo::WaiterQueue);
    return OK;
  }
  DVLOG(3) << "Waiting for endpoint " << endpoint.ToString();
  lock_info_in_map.queue->Append(waiter);
  return ERR_IO_PENDING;
}

void WebSocketEndpointLockManager::RememberSocket(StreamSocket* socket,
                                                  const IPEndPoint& endpoint) {
  LockInfoMap::iterator lock_info_it = lock_info_map_.find(endpoint);
  CHECK(lock_info_it != lock_info_map_.end());
  bool inserted =
      socket_lock_info_map_.insert(SocketLockInfoMap::value_type(
                                       socket, lock_info_it)).second;
  DCHECK(inserted);
  DCHECK(!lock_info_it->second.socket);
  lock_info_it->second.socket = socket;
  DVLOG(3) << "Remembered (StreamSocket*)" << socket << " for "
           << endpoint.ToString() << " (" << socket_lock_info_map_.size()
           << " socket(s) remembered)";
}

void WebSocketEndpointLockManager::UnlockSocket(StreamSocket* socket) {
  SocketLockInfoMap::iterator socket_it = socket_lock_info_map_.find(socket);
  if (socket_it == socket_lock_info_map_.end())
    return;

  LockInfoMap::iterator lock_info_it = socket_it->second;

  DVLOG(3) << "Unlocking (StreamSocket*)" << socket << " for "
           << lock_info_it->first.ToString() << " ("
           << socket_lock_info_map_.size() << " socket(s) left)";
  socket_lock_info_map_.erase(socket_it);
  DCHECK_EQ(socket, lock_info_it->second.socket);
  lock_info_it->second.socket = NULL;
  UnlockEndpointAfterDelay(lock_info_it->first);
}

void WebSocketEndpointLockManager::UnlockEndpoint(const IPEndPoint& endpoint) {
  LockInfoMap::iterator lock_info_it = lock_info_map_.find(endpoint);
  if (lock_info_it == lock_info_map_.end())
    return;
  if (lock_info_it->second.socket)
    EraseSocket(lock_info_it);
  UnlockEndpointAfterDelay(endpoint);
}

bool WebSocketEndpointLockManager::IsEmpty() const {
  return lock_info_map_.empty() && socket_lock_info_map_.empty();
}

base::TimeDelta WebSocketEndpointLockManager::SetUnlockDelayForTesting(
    base::TimeDelta new_delay) {
  base::TimeDelta old_delay = unlock_delay_;
  unlock_delay_ = new_delay;
  return old_delay;
}

WebSocketEndpointLockManager::LockInfo::LockInfo() : socket(NULL) {}
WebSocketEndpointLockManager::LockInfo::~LockInfo() {
  DCHECK(!socket);
}

WebSocketEndpointLockManager::LockInfo::LockInfo(const LockInfo& rhs)
    : socket(rhs.socket) {
  DCHECK(!rhs.queue);
}

WebSocketEndpointLockManager::WebSocketEndpointLockManager()
    : unlock_delay_(base::TimeDelta::FromMilliseconds(kUnlockDelayInMs)),
      pending_unlock_count_(0),
      weak_factory_(this) {
}

WebSocketEndpointLockManager::~WebSocketEndpointLockManager() {
  DCHECK_EQ(lock_info_map_.size(), pending_unlock_count_);
  DCHECK(socket_lock_info_map_.empty());
}

void WebSocketEndpointLockManager::UnlockEndpointAfterDelay(
    const IPEndPoint& endpoint) {
  DVLOG(3) << "Delaying " << unlock_delay_.InMilliseconds()
           << "ms before unlocking endpoint " << endpoint.ToString();
  ++pending_unlock_count_;
  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&WebSocketEndpointLockManager::DelayedUnlockEndpoint,
                 weak_factory_.GetWeakPtr(), endpoint),
      unlock_delay_);
}

void WebSocketEndpointLockManager::DelayedUnlockEndpoint(
    const IPEndPoint& endpoint) {
  LockInfoMap::iterator lock_info_it = lock_info_map_.find(endpoint);
  DCHECK_GT(pending_unlock_count_, 0U);
  --pending_unlock_count_;
  if (lock_info_it == lock_info_map_.end())
    return;
  DCHECK(!lock_info_it->second.socket);
  LockInfo::WaiterQueue* queue = lock_info_it->second.queue.get();
  DCHECK(queue);
  if (queue->empty()) {
    DVLOG(3) << "Unlocking endpoint " << lock_info_it->first.ToString();
    lock_info_map_.erase(lock_info_it);
    return;
  }

  DVLOG(3) << "Unlocking endpoint " << lock_info_it->first.ToString()
           << " and activating next waiter";
  Waiter* next_job = queue->head()->value();
  next_job->RemoveFromList();
  next_job->GotEndpointLock();
}

void WebSocketEndpointLockManager::EraseSocket(
    LockInfoMap::iterator lock_info_it) {
  DVLOG(3) << "Removing (StreamSocket*)" << lock_info_it->second.socket
           << " for " << lock_info_it->first.ToString() << " ("
           << socket_lock_info_map_.size() << " socket(s) left)";
  size_t erased = socket_lock_info_map_.erase(lock_info_it->second.socket);
  DCHECK_EQ(1U, erased);
  lock_info_it->second.socket = NULL;
}

}  // namespace net
