// 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 "net/tools/quic/quic_client_message_loop_network_helper.h"

#include <utility>

#include "base/logging.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/net_errors.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_info.h"
#include "net/log/net_log_source.h"
#include "net/log/net_log_with_source.h"
#include "net/quic/quic_chromium_alarm_factory.h"
#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_chromium_packet_reader.h"
#include "net/quic/quic_chromium_packet_writer.h"
#include "net/socket/udp_client_socket.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/third_party/quic/core/crypto/quic_random.h"
#include "net/third_party/quic/core/http/spdy_utils.h"
#include "net/third_party/quic/core/quic_connection.h"
#include "net/third_party/quic/core/quic_packets.h"
#include "net/third_party/quic/core/quic_server_id.h"
#include "net/third_party/quic/platform/api/quic_flags.h"
#include "net/third_party/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"

using std::string;

namespace net {

QuicClientMessageLooplNetworkHelper::QuicClientMessageLooplNetworkHelper(
    quic::QuicChromiumClock* clock,
    quic::QuicClientBase* client)
    : packet_reader_started_(false), clock_(clock), client_(client) {}

QuicClientMessageLooplNetworkHelper::~QuicClientMessageLooplNetworkHelper() =
    default;

bool QuicClientMessageLooplNetworkHelper::CreateUDPSocketAndBind(
    quic::QuicSocketAddress server_address,
    quic::QuicIpAddress bind_to_address,
    int bind_to_port) {
  auto socket = std::make_unique<UDPClientSocket>(DatagramSocket::DEFAULT_BIND,
                                                  &net_log_, NetLogSource());

  if (bind_to_address.IsInitialized()) {
    client_address_ =
        quic::QuicSocketAddress(bind_to_address, client_->local_port());
  } else if (server_address.host().address_family() ==
             quic::IpAddressFamily::IP_V4) {
    client_address_ =
        quic::QuicSocketAddress(quic::QuicIpAddress::Any4(), bind_to_port);
  } else {
    client_address_ =
        quic::QuicSocketAddress(quic::QuicIpAddress::Any6(), bind_to_port);
  }

  int rc = socket->Connect(server_address.impl().socket_address());
  if (rc != OK) {
    LOG(ERROR) << "Connect failed: " << ErrorToShortString(rc);
    return false;
  }

  rc = socket->SetReceiveBufferSize(quic::kDefaultSocketReceiveBuffer);
  if (rc != OK) {
    LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToShortString(rc);
    return false;
  }

  rc = socket->SetSendBufferSize(quic::kDefaultSocketReceiveBuffer);
  if (rc != OK) {
    LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToShortString(rc);
    return false;
  }

  IPEndPoint address;
  rc = socket->GetLocalAddress(&address);
  if (rc != OK) {
    LOG(ERROR) << "GetLocalAddress failed: " << ErrorToShortString(rc);
    return false;
  }
  client_address_ =
      quic::QuicSocketAddress(quic::QuicSocketAddressImpl(address));

  socket_.swap(socket);
  packet_reader_.reset(new QuicChromiumPacketReader(
      socket_.get(), clock_, this, kQuicYieldAfterPacketsRead,
      quic::QuicTime::Delta::FromMilliseconds(
          kQuicYieldAfterDurationMilliseconds),
      NetLogWithSource()));

  if (socket != nullptr) {
    socket->Close();
  }

  return true;
}

void QuicClientMessageLooplNetworkHelper::CleanUpAllUDPSockets() {
  client_->reset_writer();
  packet_reader_.reset();
  packet_reader_started_ = false;
}

void QuicClientMessageLooplNetworkHelper::StartPacketReaderIfNotStarted() {
  if (!packet_reader_started_) {
    packet_reader_->StartReading();
    packet_reader_started_ = true;
  }
}

void QuicClientMessageLooplNetworkHelper::RunEventLoop() {
  StartPacketReaderIfNotStarted();
  base::RunLoop().RunUntilIdle();
}

quic::QuicPacketWriter*
QuicClientMessageLooplNetworkHelper::CreateQuicPacketWriter() {
  return new QuicChromiumPacketWriter(
      socket_.get(), base::ThreadTaskRunnerHandle::Get().get());
}

void QuicClientMessageLooplNetworkHelper::OnReadError(
    int result,
    const DatagramClientSocket* socket) {
  LOG(ERROR) << "QuicSimpleClient read failed: " << ErrorToShortString(result);
  client_->Disconnect();
}

quic::QuicSocketAddress
QuicClientMessageLooplNetworkHelper::GetLatestClientAddress() const {
  return client_address_;
}

bool QuicClientMessageLooplNetworkHelper::OnPacket(
    const quic::QuicReceivedPacket& packet,
    const quic::QuicSocketAddress& local_address,
    const quic::QuicSocketAddress& peer_address) {
  client_->session()->connection()->ProcessUdpPacket(local_address,
                                                     peer_address, packet);
  if (!client_->session()->connection()->connected()) {
    return false;
  }

  return true;
}

}  // namespace net
