// 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,
        client_->masque_encapsulated_client_session());
    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_, masque_encapsulated_client_session());
}

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
