// Copyright (c) 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.

// Sets up a dispatcher and sends requests via the QboneClient.

#include "net/third_party/quiche/src/quic/qbone/qbone_client.h"

#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h"
#include "net/third_party/quiche/src/quic/core/quic_default_packet_writer.h"
#include "net/third_party/quiche/src/quic/core/quic_dispatcher.h"
#include "net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h"
#include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h"
#include "net/third_party/quiche/src/quic/core/quic_packet_reader.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_port_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h"
#include "net/quic/platform/impl/quic_socket_utils.h"
#include "net/third_party/quiche/src/quic/qbone/qbone_constants.h"
#include "net/third_party/quiche/src/quic/qbone/qbone_packet_processor_test_tools.h"
#include "net/third_party/quiche/src/quic/qbone/qbone_server_session.h"
#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_server_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/server_thread.h"
#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
#include "net/third_party/quiche/src/quic/tools/quic_server.h"

namespace quic {
namespace test {
namespace {

string TestPacketIn(const string& body) {
  return PrependIPv6HeaderForTest(body, 5);
}

string TestPacketOut(const string& body) {
  return PrependIPv6HeaderForTest(body, 4);
}

class DataSavingQbonePacketWriter : public QbonePacketWriter {
 public:
  void WritePacketToNetwork(const char* packet, size_t size) override {
    QuicWriterMutexLock lock(&mu_);
    data_.push_back(string(packet, size));
  }

  std::vector<string> data() {
    QuicWriterMutexLock lock(&mu_);
    return data_;
  }

 private:
  QuicMutex mu_;
  std::vector<string> data_;
};

// A subclass of a qbone session that will own the connection passed in.
class ConnectionOwningQboneServerSession : public QboneServerSession {
 public:
  ConnectionOwningQboneServerSession(
      const ParsedQuicVersionVector& supported_versions,
      QuicConnection* connection,
      Visitor* owner,
      const QuicConfig& config,
      const QuicCryptoServerConfig* quic_crypto_server_config,
      QuicCompressedCertsCache* compressed_certs_cache,
      QbonePacketWriter* writer)
      : QboneServerSession(supported_versions,
                           connection,
                           owner,
                           config,
                           quic_crypto_server_config,
                           compressed_certs_cache,
                           writer,
                           TestLoopback6(),
                           TestLoopback6(),
                           64,
                           nullptr),
        connection_(connection) {}

 private:
  // Note that we don't expect the QboneServerSession or any of its parent
  // classes to do anything with the connection_ in their destructors.
  std::unique_ptr<QuicConnection> connection_;
};

class QuicQboneDispatcher : public QuicDispatcher {
 public:
  QuicQboneDispatcher(
      const QuicConfig* config,
      const QuicCryptoServerConfig* crypto_config,
      QuicVersionManager* version_manager,
      std::unique_ptr<QuicConnectionHelperInterface> helper,
      std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
      std::unique_ptr<QuicAlarmFactory> alarm_factory,
      QbonePacketWriter* writer)
      : QuicDispatcher(config,
                       crypto_config,
                       version_manager,
                       std::move(helper),
                       std::move(session_helper),
                       std::move(alarm_factory),
                       kQuicDefaultConnectionIdLength),
        writer_(writer) {}

  QuicSession* CreateQuicSession(
      QuicConnectionId id,
      const QuicSocketAddress& client,
      QuicStringPiece alpn,
      const quic::ParsedQuicVersion& version) override {
    CHECK_EQ(alpn, "qbone");
    QuicConnection* connection =
        new QuicConnection(id, client, helper(), alarm_factory(), writer(),
                           /* owns_writer= */ false, Perspective::IS_SERVER,
                           ParsedQuicVersionVector{version});
    // The connection owning wrapper owns the connection created.
    QboneServerSession* session = new ConnectionOwningQboneServerSession(
        GetSupportedVersions(), connection, this, config(), crypto_config(),
        compressed_certs_cache(), writer_);
    session->Initialize();
    return session;
  }

  QuicConnectionId GenerateNewServerConnectionId(
      ParsedQuicVersion version,
      QuicConnectionId connection_id) const override {
    char connection_id_bytes[kQuicDefaultConnectionIdLength] = {};
    return QuicConnectionId(connection_id_bytes, sizeof(connection_id_bytes));
  }

 private:
  QbonePacketWriter* writer_;
};

class QboneTestServer : public QuicServer {
 public:
  explicit QboneTestServer(std::unique_ptr<ProofSource> proof_source)
      : QuicServer(std::move(proof_source), &response_cache_) {}
  QuicDispatcher* CreateQuicDispatcher() override {
    QuicEpollAlarmFactory alarm_factory(epoll_server());
    return new QuicQboneDispatcher(
        &config(), &crypto_config(), version_manager(),
        std::unique_ptr<QuicEpollConnectionHelper>(
            new QuicEpollConnectionHelper(epoll_server(),
                                          QuicAllocator::BUFFER_POOL)),
        std::unique_ptr<QuicCryptoServerStream::Helper>(
            new QboneCryptoServerStreamHelper()),
        std::unique_ptr<QuicEpollAlarmFactory>(
            new QuicEpollAlarmFactory(epoll_server())),
        &writer_);
  }

  std::vector<string> data() { return writer_.data(); }

  void WaitForDataSize(int n) {
    while (data().size() != n) {
    }
  }

 private:
  quic::QuicMemoryCacheBackend response_cache_;
  DataSavingQbonePacketWriter writer_;
};

class QboneTestClient : public QboneClient {
 public:
  QboneTestClient(QuicSocketAddress server_address,
                  const QuicServerId& server_id,
                  const ParsedQuicVersionVector& supported_versions,
                  QuicEpollServer* epoll_server,
                  std::unique_ptr<ProofVerifier> proof_verifier)
      : QboneClient(server_address,
                    server_id,
                    supported_versions,
                    /*session_owner=*/nullptr,
                    QuicConfig(),
                    epoll_server,
                    std::move(proof_verifier),
                    &qbone_writer_,
                    nullptr) {}

  ~QboneTestClient() override {}

  void SendData(const string& data) {
    qbone_session()->ProcessPacketFromNetwork(data);
  }

  void WaitForWriteToFlush() {
    while (connected() && session()->HasDataToWrite()) {
      WaitForEvents();
    }
  }

  void WaitForDataSize(int n) {
    while (data().size() != n) {
      WaitForEvents();
    }
  }

  std::vector<string> data() { return qbone_writer_.data(); }

 private:
  DataSavingQbonePacketWriter qbone_writer_;
};

TEST(QboneClientTest, SendDataFromClient) {
  SetQuicReloadableFlag(quic_use_parse_public_header, true);
  auto server = new QboneTestServer(crypto_test_utils::ProofSourceForTesting());
  QuicSocketAddress server_address(TestLoopback(),
                                   QuicPickServerPortForTestsOrDie());
  ServerThread server_thread(server, server_address);
  server_thread.Initialize();
  server_thread.Start();

  QuicEpollServer epoll_server;
  QboneTestClient client(
      server_address,
      QuicServerId("test.example.com", server_address.port(), false),
      AllSupportedVersions(), &epoll_server,
      crypto_test_utils::ProofVerifierForTesting());
  ASSERT_TRUE(client.Initialize());
  ASSERT_TRUE(client.Connect());
  ASSERT_TRUE(client.WaitForCryptoHandshakeConfirmed());
  client.SendData(TestPacketIn("hello"));
  client.SendData(TestPacketIn("world"));
  client.WaitForWriteToFlush();
  server->WaitForDataSize(2);
  EXPECT_THAT(server->data()[0], testing::Eq(TestPacketOut("hello")));
  EXPECT_THAT(server->data()[1], testing::Eq(TestPacketOut("world")));
  auto server_session =
      static_cast<QboneServerSession*>(QuicServerPeer::GetDispatcher(server)
                                           ->session_map()
                                           .begin()
                                           ->second.get());
  string long_data(QboneConstants::kMaxQbonePacketBytes - sizeof(ip6_hdr) - 1,
                   'A');
  // Pretend the server gets data.
  server_thread.Schedule([&server_session, &long_data]() {
    server_session->ProcessPacketFromNetwork(
        TestPacketIn("Somethingsomething"));
    server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
    server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
  });
  client.WaitForDataSize(3);
  EXPECT_THAT(client.data()[0],
              testing::Eq(TestPacketOut("Somethingsomething")));
  EXPECT_THAT(client.data()[1], testing::Eq(TestPacketOut(long_data)));
  EXPECT_THAT(client.data()[2], testing::Eq(TestPacketOut(long_data)));

  client.Disconnect();
  server_thread.Quit();
  server_thread.Join();
}

}  // namespace
}  // namespace test
}  // namespace quic
