// 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 "quiche/quic/qbone/qbone_client.h"

#include "absl/strings/string_view.h"
#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_default_connection_helper.h"
#include "quiche/quic/core/quic_default_packet_writer.h"
#include "quiche/quic/core/quic_dispatcher.h"
#include "quiche/quic/core/quic_epoll_alarm_factory.h"
#include "quiche/quic/core/quic_epoll_connection_helper.h"
#include "quiche/quic/core/quic_packet_reader.h"
#include "quiche/quic/platform/api/quic_mutex.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/platform/api/quic_test_loopback.h"
#include "quiche/quic/qbone/qbone_constants.h"
#include "quiche/quic/qbone/qbone_packet_processor_test_tools.h"
#include "quiche/quic/qbone/qbone_server_session.h"
#include "quiche/quic/test_tools/crypto_test_utils.h"
#include "quiche/quic/test_tools/quic_connection_peer.h"
#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
#include "quiche/quic/test_tools/quic_server_peer.h"
#include "quiche/quic/test_tools/server_thread.h"
#include "quiche/quic/tools/quic_memory_cache_backend.h"
#include "quiche/quic/tools/quic_server.h"

namespace quic {
namespace test {
namespace {

using ::testing::ElementsAre;

ParsedQuicVersionVector GetTestParams() {
  ParsedQuicVersionVector test_versions;

  // TODO(b/113130636): Make QBONE work with TLS.
  for (const auto& version : CurrentSupportedVersionsWithQuicCrypto()) {
    // QBONE requires MESSAGE frames
    if (!version.SupportsMessageFrames()) {
      continue;
    }
    test_versions.push_back(version);
  }

  return test_versions;
}

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

std::string TestPacketOut(const std::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(std::string(packet, size));
  }

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

 private:
  QuicMutex mu_;
  std::vector<std::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<QuicCryptoServerStreamBase::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) {}

  std::unique_ptr<QuicSession> CreateQuicSession(
      QuicConnectionId id, const QuicSocketAddress& self_address,
      const QuicSocketAddress& peer_address, absl::string_view alpn,
      const ParsedQuicVersion& version,
      const ParsedClientHello& /*parsed_chlo*/) override {
    QUICHE_CHECK_EQ(alpn, "qbone");
    QuicConnection* connection = new QuicConnection(
        id, self_address, peer_address, helper(), alarm_factory(), writer(),
        /* owns_writer= */ false, Perspective::IS_SERVER,
        ParsedQuicVersionVector{version});
    // The connection owning wrapper owns the connection created.
    auto session = std::make_unique<ConnectionOwningQboneServerSession>(
        GetSupportedVersions(), connection, this, config(), crypto_config(),
        compressed_certs_cache(), writer_);
    session->Initialize();
    return session;
  }

 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 {
    return new QuicQboneDispatcher(
        &config(), &crypto_config(), version_manager(),
        std::make_unique<QuicDefaultConnectionHelper>(),
        std::make_unique<QboneCryptoServerStreamHelper>(),
        event_loop()->CreateAlarmFactory(), &writer_);
  }

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

 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 std::string& data) {
    qbone_session()->ProcessPacketFromNetwork(data);
  }

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

  // Returns true when the data size is reached or false on timeouts.
  bool WaitForDataSize(int n, QuicTime::Delta timeout) {
    const QuicClock* clock =
        quic::test::QuicConnectionPeer::GetHelper(session()->connection())
            ->GetClock();
    const QuicTime deadline = clock->Now() + timeout;
    while (data().size() < n) {
      if (clock->Now() > deadline) {
        return false;
      }
      WaitForEvents();
    }
    return true;
  }

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

 private:
  DataSavingQbonePacketWriter qbone_writer_;
};

class QboneClientTest : public QuicTestWithParam<ParsedQuicVersion> {};

INSTANTIATE_TEST_SUITE_P(Tests, QboneClientTest,
                         ::testing::ValuesIn(GetTestParams()),
                         ::testing::PrintToStringParamName());

TEST_P(QboneClientTest, SendDataFromClient) {
  auto server = std::make_unique<QboneTestServer>(
      crypto_test_utils::ProofSourceForTesting());
  QboneTestServer* server_ptr = server.get();
  QuicSocketAddress server_address(TestLoopback(), 0);
  ServerThread server_thread(std::move(server), server_address);
  server_thread.Initialize();
  server_address =
      QuicSocketAddress(server_address.host(), server_thread.GetPort());
  server_thread.Start();

  QuicEpollServer epoll_server;
  QboneTestClient client(
      server_address,
      QuicServerId("test.example.com", server_address.port(), false),
      ParsedQuicVersionVector{GetParam()}, &epoll_server,
      crypto_test_utils::ProofVerifierForTesting());
  ASSERT_TRUE(client.Initialize());
  ASSERT_TRUE(client.Connect());
  ASSERT_TRUE(client.WaitForOneRttKeysAvailable());
  client.SendData(TestPacketIn("hello"));
  client.SendData(TestPacketIn("world"));
  client.WaitForWriteToFlush();

  // Wait until the server has received at least two packets, timeout after 5s.
  ASSERT_TRUE(
      server_thread.WaitUntil([&] { return server_ptr->data().size() >= 2; },
                              QuicTime::Delta::FromSeconds(5)));

  // Pretend the server gets data.
  std::string long_data(1000, 'A');
  server_thread.Schedule([server_ptr, &long_data]() {
    EXPECT_THAT(server_ptr->data(),
                ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
    auto server_session = static_cast<QboneServerSession*>(
        QuicDispatcherPeer::GetFirstSessionIfAny(
            QuicServerPeer::GetDispatcher(server_ptr)));
    server_session->ProcessPacketFromNetwork(
        TestPacketIn("Somethingsomething"));
    server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
    server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
  });

  EXPECT_TRUE(client.WaitForDataSize(3, QuicTime::Delta::FromSeconds(5)));
  EXPECT_THAT(client.data(),
              ElementsAre(TestPacketOut("Somethingsomething"),
                          TestPacketOut(long_data), TestPacketOut(long_data)));

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

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