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

#include "base/logging.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/websocket_endpoint_lock_manager.h"

namespace net {

WebSocketTransportConnectSubJob::WebSocketTransportConnectSubJob(
    const AddressList& addresses,
    WebSocketTransportConnectJob* parent_job,
    SubJobType type,
    WebSocketEndpointLockManager* websocket_endpoint_lock_manager)
    : parent_job_(parent_job),
      addresses_(addresses),
      current_address_index_(0),
      next_state_(STATE_NONE),
      type_(type),
      websocket_endpoint_lock_manager_(websocket_endpoint_lock_manager) {}

WebSocketTransportConnectSubJob::~WebSocketTransportConnectSubJob() {
  // We don't worry about cancelling the TCP connect, since ~StreamSocket will
  // take care of it.
  if (next()) {
    DCHECK_EQ(STATE_OBTAIN_LOCK_COMPLETE, next_state_);
    // The ~Waiter destructor will remove this object from the waiting list.
  } else if (next_state_ == STATE_TRANSPORT_CONNECT_COMPLETE) {
    websocket_endpoint_lock_manager_->UnlockEndpoint(CurrentAddress());
  }
}

// Start connecting.
int WebSocketTransportConnectSubJob::Start() {
  DCHECK_EQ(STATE_NONE, next_state_);
  next_state_ = STATE_OBTAIN_LOCK;
  return DoLoop(OK);
}

// Called by WebSocketEndpointLockManager when the lock becomes available.
void WebSocketTransportConnectSubJob::GotEndpointLock() {
  DCHECK_EQ(STATE_OBTAIN_LOCK_COMPLETE, next_state_);
  OnIOComplete(OK);
}

LoadState WebSocketTransportConnectSubJob::GetLoadState() const {
  switch (next_state_) {
    case STATE_OBTAIN_LOCK:
    case STATE_OBTAIN_LOCK_COMPLETE:
      // TODO(ricea): Add a WebSocket-specific LOAD_STATE ?
      return LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET;
    case STATE_TRANSPORT_CONNECT:
    case STATE_TRANSPORT_CONNECT_COMPLETE:
    case STATE_DONE:
      return LOAD_STATE_CONNECTING;
    case STATE_NONE:
      return LOAD_STATE_IDLE;
  }
  NOTREACHED();
  return LOAD_STATE_IDLE;
}

ClientSocketFactory* WebSocketTransportConnectSubJob::client_socket_factory()
    const {
  return parent_job_->client_socket_factory_;
}

const NetLogWithSource& WebSocketTransportConnectSubJob::net_log() const {
  return parent_job_->net_log();
}

const IPEndPoint& WebSocketTransportConnectSubJob::CurrentAddress() const {
  DCHECK_LT(current_address_index_, addresses_.size());
  return addresses_[current_address_index_];
}

void WebSocketTransportConnectSubJob::OnIOComplete(int result) {
  int rv = DoLoop(result);
  if (rv != ERR_IO_PENDING)
    parent_job_->OnSubJobComplete(rv, this);  // |this| deleted
}

int WebSocketTransportConnectSubJob::DoLoop(int result) {
  DCHECK_NE(next_state_, STATE_NONE);

  int rv = result;
  do {
    State state = next_state_;
    next_state_ = STATE_NONE;
    switch (state) {
      case STATE_OBTAIN_LOCK:
        DCHECK_EQ(OK, rv);
        rv = DoEndpointLock();
        break;
      case STATE_OBTAIN_LOCK_COMPLETE:
        DCHECK_EQ(OK, rv);
        rv = DoEndpointLockComplete();
        break;
      case STATE_TRANSPORT_CONNECT:
        DCHECK_EQ(OK, rv);
        rv = DoTransportConnect();
        break;
      case STATE_TRANSPORT_CONNECT_COMPLETE:
        rv = DoTransportConnectComplete(rv);
        break;
      default:
        NOTREACHED();
        rv = ERR_FAILED;
        break;
    }
  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE &&
           next_state_ != STATE_DONE);

  return rv;
}

int WebSocketTransportConnectSubJob::DoEndpointLock() {
  int rv =
      websocket_endpoint_lock_manager_->LockEndpoint(CurrentAddress(), this);
  next_state_ = STATE_OBTAIN_LOCK_COMPLETE;
  return rv;
}

int WebSocketTransportConnectSubJob::DoEndpointLockComplete() {
  next_state_ = STATE_TRANSPORT_CONNECT;
  return OK;
}

int WebSocketTransportConnectSubJob::DoTransportConnect() {
  // TODO(ricea): Update global g_last_connect_time and report
  // ConnectInterval.
  next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
  AddressList one_address(CurrentAddress());
  transport_socket_ = client_socket_factory()->CreateTransportClientSocket(
      one_address, nullptr, net_log().net_log(), net_log().source());
  // This use of base::Unretained() is safe because transport_socket_ is
  // destroyed in the destructor.
  return transport_socket_->Connect(base::Bind(
      &WebSocketTransportConnectSubJob::OnIOComplete, base::Unretained(this)));
}

int WebSocketTransportConnectSubJob::DoTransportConnectComplete(int result) {
  next_state_ = STATE_DONE;
  if (result != OK) {
    websocket_endpoint_lock_manager_->UnlockEndpoint(CurrentAddress());

    if (current_address_index_ + 1 < addresses_.size()) {
      // Try falling back to the next address in the list.
      next_state_ = STATE_OBTAIN_LOCK;
      ++current_address_index_;
      result = OK;
    }

    return result;
  }

  websocket_endpoint_lock_manager_->RememberSocket(transport_socket_.get(),
                                                   CurrentAddress());

  return result;
}

}  // namespace net
