// Copyright 2015 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/quic/p2p/quic_p2p_session.h"

#include "base/callback_helpers.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/quic/p2p/quic_p2p_crypto_stream.h"
#include "net/quic/p2p/quic_p2p_stream.h"
#include "net/quic/quic_connection.h"
#include "net/socket/socket.h"

namespace net {

QuicP2PSession::QuicP2PSession(const QuicConfig& config,
                               const QuicP2PCryptoConfig& crypto_config,
                               scoped_ptr<QuicConnection> connection,
                               scoped_ptr<net::Socket> socket)
    : QuicSession(connection.release(), config),
      socket_(socket.Pass()),
      crypto_stream_(new QuicP2PCryptoStream(this, crypto_config)),
      read_buffer_(new net::IOBuffer(static_cast<size_t>(kMaxPacketSize))) {
  DCHECK(config.negotiated());

  // Non-null IP address needs to be passed here because QuicConnection uses
  // ToString() to format addresses for logging and ToString() is not allowed
  // for empty addresses.
  // TODO(sergeyu): Fix QuicConnection and remove SetSelfAddress() call below.
  net::IPAddressNumber ip(net::kIPv4AddressSize, 0);
  this->connection()->SetSelfAddress(net::IPEndPoint(ip, 0));
}

QuicP2PSession::~QuicP2PSession() {}

void QuicP2PSession::Initialize() {
  QuicSession::Initialize();
  crypto_stream_->Connect();
  DoReadLoop(OK);
}

void QuicP2PSession::SetDelegate(Delegate* delegate) {
  delegate_ = delegate;
}

QuicCryptoStream* QuicP2PSession::GetCryptoStream() {
  return crypto_stream_.get();
}

QuicP2PStream* QuicP2PSession::CreateIncomingDynamicStream(QuicStreamId id) {
  QuicP2PStream* stream = new QuicP2PStream(id, this);
  if (delegate_) {
    delegate_->OnIncomingStream(stream);
  }
  return stream;
}

QuicP2PStream* QuicP2PSession::CreateOutgoingDynamicStream() {
  QuicP2PStream* stream = new QuicP2PStream(GetNextStreamId(), this);
  if (stream) {
    ActivateStream(stream);
  }
  return stream;
}

void QuicP2PSession::OnConnectionClosed(QuicErrorCode error, bool from_peer) {
  QuicSession::OnConnectionClosed(error, from_peer);

  socket_.reset();

  if (delegate_) {
    Delegate* delegate = delegate_;
    delegate_ = nullptr;
    delegate->OnConnectionClosed(error);
  }
}

void QuicP2PSession::DoReadLoop(int result) {
  while (error() == net::QUIC_NO_ERROR) {
    switch (read_state_) {
      case READ_STATE_DO_READ:
        CHECK_EQ(result, OK);
        result = DoRead();
        break;
      case READ_STATE_DO_READ_COMPLETE:
        result = DoReadComplete(result);
        break;
      default:
        NOTREACHED() << "read_state_: " << read_state_;
        break;
    }

    if (result < 0)
      break;
  }
}

int QuicP2PSession::DoRead() {
  DCHECK_EQ(read_state_, READ_STATE_DO_READ);
  read_state_ = READ_STATE_DO_READ_COMPLETE;

  if (!socket_) {
    return net::ERR_SOCKET_NOT_CONNECTED;
  }

  return socket_->Read(
      read_buffer_.get(), kMaxPacketSize,
      base::Bind(&QuicP2PSession::DoReadLoop, base::Unretained(this)));
}

int QuicP2PSession::DoReadComplete(int result) {
  DCHECK_EQ(read_state_, READ_STATE_DO_READ_COMPLETE);
  read_state_ = READ_STATE_DO_READ;

  if (result <= 0) {
    connection()->CloseConnection(net::QUIC_PACKET_READ_ERROR, false);
    return result;
  }

  QuicEncryptedPacket packet(read_buffer_->data(), result);
  connection()->ProcessUdpPacket(connection()->self_address(),
                                 connection()->peer_address(), packet);
  return OK;
}

}  // namespace net
