// 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 "quic/masque/masque_encapsulated_epoll_client.h"
#include "quic/core/quic_utils.h"
#include "quic/masque/masque_client_session.h"
#include "quic/masque/masque_encapsulated_client_session.h"
#include "quic/masque/masque_epoll_client.h"
#include "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:
  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 {
    QUICHE_DCHECK(peer_address.IsInitialized());
    QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len
                  << " bytes to " << peer_address;
    absl::string_view 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; }
  QuicPacketBuffer GetNextWriteLocation(
      const QuicIpAddress& /*self_address*/,
      const QuicSocketAddress& /*peer_address*/) override {
    return {nullptr, 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
