// Copyright 2019 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/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/masque/masque_client_session.h"
#include "net/third_party/quiche/src/quic/masque/masque_encapsulated_client_session.h"
#include "net/third_party/quiche/src/quic/masque/masque_epoll_client.h"
#include "net/third_party/quiche/src/quic/masque/masque_utils.h"

namespace quic {

namespace {

// Custom packet writer that allows getting all of a connection's outgoing
// packets.
class MasquePacketWriter : public QuicPacketWriter {
 public:
  MasquePacketWriter() = delete;
  explicit MasquePacketWriter(MasqueEncapsulatedEpollClient* client)
      : client_(client) {}
  WriteResult WritePacket(const char* buffer,
                          size_t buf_len,
                          const QuicIpAddress& /*self_address*/,
                          const QuicSocketAddress& peer_address,
                          PerPacketOptions* /*options*/) override {
    DCHECK(peer_address.IsInitialized());
    QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len
                  << " bytes to " << peer_address;
    QuicStringPiece packet(buffer, buf_len);
    client_->masque_client()->masque_client_session()->SendPacket(
        client_->session()->connection()->client_connection_id(),
        client_->session()->connection()->connection_id(), packet,
        peer_address);
    return WriteResult(WRITE_STATUS_OK, buf_len);
  }

  bool IsWriteBlocked() const override { return false; }

  void SetWritable() override {}

  QuicByteCount GetMaxPacketSize(
      const QuicSocketAddress& /*peer_address*/) const override {
    return kMasqueMaxEncapsulatedPacketSize;
  }

  bool SupportsReleaseTime() const override { return false; }

  bool IsBatchMode() const override { return false; }
  char* GetNextWriteLocation(
      const QuicIpAddress& /*self_address*/,
      const QuicSocketAddress& /*peer_address*/) override {
    return nullptr;
  }

  WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }

 private:
  MasqueEncapsulatedEpollClient* client_;  // Unowned.
};

// Custom network helper that allows injecting a custom packet writer in order
// to get all of a connection's outgoing packets.
class MasqueClientEpollNetworkHelper : public QuicClientEpollNetworkHelper {
 public:
  MasqueClientEpollNetworkHelper(QuicEpollServer* epoll_server,
                                 MasqueEncapsulatedEpollClient* client)
      : QuicClientEpollNetworkHelper(epoll_server, client), client_(client) {}
  QuicPacketWriter* CreateQuicPacketWriter() override {
    return new MasquePacketWriter(client_);
  }

 private:
  MasqueEncapsulatedEpollClient* client_;  // Unowned.
};

}  // namespace

MasqueEncapsulatedEpollClient::MasqueEncapsulatedEpollClient(
    QuicSocketAddress server_address,
    const QuicServerId& server_id,
    QuicEpollServer* epoll_server,
    std::unique_ptr<ProofVerifier> proof_verifier,
    MasqueEpollClient* masque_client)
    : QuicClient(
          server_address,
          server_id,
          MasqueSupportedVersions(),
          MasqueEncapsulatedConfig(),
          epoll_server,
          std::make_unique<MasqueClientEpollNetworkHelper>(epoll_server, this),
          std::move(proof_verifier)),
      masque_client_(masque_client) {}

MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() {
  masque_client_->masque_client_session()->UnregisterConnectionId(
      client_connection_id_);
}

std::unique_ptr<QuicSession>
MasqueEncapsulatedEpollClient::CreateQuicClientSession(
    const ParsedQuicVersionVector& supported_versions,
    QuicConnection* connection) {
  QUIC_DLOG(INFO) << "Creating MASQUE encapsulated session for "
                  << connection->connection_id();
  return std::make_unique<MasqueEncapsulatedClientSession>(
      *config(), supported_versions, connection, server_id(), crypto_config(),
      push_promise_index(), masque_client_->masque_client_session());
}

MasqueEncapsulatedClientSession*
MasqueEncapsulatedEpollClient::masque_encapsulated_client_session() {
  return static_cast<MasqueEncapsulatedClientSession*>(QuicClient::session());
}

QuicConnectionId MasqueEncapsulatedEpollClient::GetClientConnectionId() {
  if (client_connection_id_.IsEmpty()) {
    client_connection_id_ = QuicUtils::CreateRandomConnectionId();
    masque_client_->masque_client_session()->RegisterConnectionId(
        client_connection_id_, masque_encapsulated_client_session());
  }
  return client_connection_id_;
}

}  // namespace quic
