// 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.

// An integration test that covers interactions between QuicTransport client and
// server sessions.

#include <memory>
#include <vector>

#include "url/gurl.h"
#include "url/origin.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
#include "net/third_party/quiche/src/quic/core/quic_connection.h"
#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_optional.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h"
#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h"
#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h"
#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h"
#include "net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h"

namespace quic {
namespace test {
namespace {

using simulator::QuicEndpointBase;
using simulator::Simulator;
using testing::Assign;

url::Origin GetTestOrigin() {
  constexpr char kTestOrigin[] = "https://test-origin.test";
  GURL origin_url(kTestOrigin);
  return url::Origin::Create(origin_url);
}

ParsedQuicVersionVector GetVersions() {
  return {ParsedQuicVersion{PROTOCOL_TLS1_3, QUIC_VERSION_99}};
}

class QuicTransportEndpointBase : public QuicEndpointBase {
 public:
  QuicTransportEndpointBase(Simulator* simulator,
                            const std::string& name,
                            const std::string& peer_name,
                            Perspective perspective)
      : QuicEndpointBase(simulator, name, peer_name) {
    connection_ = std::make_unique<QuicConnection>(
        TestConnectionId(0x10), simulator::GetAddressFromName(peer_name),
        simulator, simulator->GetAlarmFactory(), &writer_,
        /*owns_writer=*/false, perspective, GetVersions());
    connection_->SetSelfAddress(simulator::GetAddressFromName(name));
  }
};

class QuicTransportClientEndpoint : public QuicTransportEndpointBase {
 public:
  QuicTransportClientEndpoint(Simulator* simulator,
                              const std::string& name,
                              const std::string& peer_name,
                              const QuicConfig& config,
                              url::Origin origin,
                              const std::string& path)
      : QuicTransportEndpointBase(simulator,
                                  name,
                                  peer_name,
                                  Perspective::IS_CLIENT),
        crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
        session_(connection_.get(),
                 nullptr,
                 config,
                 GetVersions(),
                 GURL("quic-transport://test.example.com:50000" + path),
                 &crypto_config_,
                 origin,
                 &visitor_) {
    session_.Initialize();
  }

  QuicTransportClientSession* session() { return &session_; }
  MockClientVisitor* visitor() { return &visitor_; }

 private:
  QuicCryptoClientConfig crypto_config_;
  MockClientVisitor visitor_;
  QuicTransportClientSession session_;
};

class QuicTransportServerEndpoint : public QuicTransportEndpointBase {
 public:
  QuicTransportServerEndpoint(Simulator* simulator,
                              const std::string& name,
                              const std::string& peer_name,
                              const QuicConfig& config,
                              std::vector<url::Origin> accepted_origins)
      : QuicTransportEndpointBase(simulator,
                                  name,
                                  peer_name,
                                  Perspective::IS_SERVER),
        crypto_config_(QuicCryptoServerConfig::TESTING,
                       QuicRandom::GetInstance(),
                       crypto_test_utils::ProofSourceForTesting(),
                       KeyExchangeSource::Default()),
        compressed_certs_cache_(
            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
        session_(connection_.get(),
                 /*owns_connection=*/false,
                 nullptr,
                 config,
                 GetVersions(),
                 &crypto_config_,
                 &compressed_certs_cache_,
                 accepted_origins) {
    session_.Initialize();
  }

  QuicTransportServerSession* session() { return &session_; }

 private:
  QuicCryptoServerConfig crypto_config_;
  QuicCompressedCertsCache compressed_certs_cache_;
  QuicTransportSimpleServerSession session_;
};

std::unique_ptr<MockStreamVisitor> VisitorExpectingFin() {
  auto visitor = std::make_unique<MockStreamVisitor>();
  EXPECT_CALL(*visitor, OnFinRead());
  return visitor;
}

constexpr QuicBandwidth kClientBandwidth =
    QuicBandwidth::FromKBitsPerSecond(10000);
constexpr QuicTime::Delta kClientPropagationDelay =
    QuicTime::Delta::FromMilliseconds(2);
constexpr QuicBandwidth kServerBandwidth =
    QuicBandwidth::FromKBitsPerSecond(4000);
constexpr QuicTime::Delta kServerPropagationDelay =
    QuicTime::Delta::FromMilliseconds(50);
const QuicTime::Delta kTransferTime =
    kClientBandwidth.TransferTime(kMaxOutgoingPacketSize) +
    kServerBandwidth.TransferTime(kMaxOutgoingPacketSize);
const QuicTime::Delta kRtt =
    (kClientPropagationDelay + kServerPropagationDelay + kTransferTime) * 2;
const QuicByteCount kBdp = kRtt * kServerBandwidth;

constexpr QuicTime::Delta kDefaultTimeout = QuicTime::Delta::FromSeconds(3);

class QuicTransportIntegrationTest : public QuicTest {
 public:
  QuicTransportIntegrationTest()
      : switch_(&simulator_, "Switch", 8, 2 * kBdp) {}

  void CreateDefaultEndpoints(const std::string& path) {
    client_ = std::make_unique<QuicTransportClientEndpoint>(
        &simulator_, "Client", "Server", client_config_, GetTestOrigin(), path);
    server_ = std::make_unique<QuicTransportServerEndpoint>(
        &simulator_, "Server", "Client", server_config_, accepted_origins_);
  }

  void WireUpEndpoints() {
    client_link_ = std::make_unique<simulator::SymmetricLink>(
        client_.get(), switch_.port(1), kClientBandwidth,
        kClientPropagationDelay);
    server_link_ = std::make_unique<simulator::SymmetricLink>(
        server_.get(), switch_.port(2), kServerBandwidth,
        kServerPropagationDelay);
  }

  void RunHandshake() {
    client_->session()->CryptoConnect();
    bool result = simulator_.RunUntilOrTimeout(
        [this]() {
          return IsHandshakeDone(client_->session()) &&
                 IsHandshakeDone(server_->session());
        },
        kDefaultTimeout);
    EXPECT_TRUE(result);
  }

 protected:
  template <class Session>
  static bool IsHandshakeDone(const Session* session) {
    return session->IsSessionReady() || session->error() != QUIC_NO_ERROR;
  }

  QuicConfig client_config_ = DefaultQuicConfig();
  QuicConfig server_config_ = DefaultQuicConfig();

  Simulator simulator_;
  simulator::Switch switch_;
  std::unique_ptr<simulator::SymmetricLink> client_link_;
  std::unique_ptr<simulator::SymmetricLink> server_link_;

  std::unique_ptr<QuicTransportClientEndpoint> client_;
  std::unique_ptr<QuicTransportServerEndpoint> server_;

  std::vector<url::Origin> accepted_origins_ = {GetTestOrigin()};
};

TEST_F(QuicTransportIntegrationTest, SuccessfulHandshake) {
  CreateDefaultEndpoints("/discard");
  WireUpEndpoints();
  EXPECT_CALL(*client_->visitor(), OnSessionReady());
  RunHandshake();
  EXPECT_TRUE(client_->session()->IsSessionReady());
  EXPECT_TRUE(server_->session()->IsSessionReady());
}

TEST_F(QuicTransportIntegrationTest, OriginMismatch) {
  accepted_origins_ = {url::Origin::Create(GURL{"https://wrong-origin.test"})};
  CreateDefaultEndpoints("/discard");
  WireUpEndpoints();
  RunHandshake();
  // Wait until the client receives CONNECTION_CLOSE.
  simulator_.RunUntilOrTimeout(
      [this]() { return !client_->session()->connection()->connected(); },
      kDefaultTimeout);
  EXPECT_TRUE(client_->session()->IsSessionReady());
  EXPECT_FALSE(server_->session()->IsSessionReady());
  EXPECT_FALSE(client_->session()->connection()->connected());
  EXPECT_FALSE(server_->session()->connection()->connected());
  EXPECT_THAT(client_->session()->error(),
              IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION));
  EXPECT_THAT(server_->session()->error(),
              IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION));
}

TEST_F(QuicTransportIntegrationTest, SendOutgoingStreams) {
  CreateDefaultEndpoints("/discard");
  WireUpEndpoints();
  RunHandshake();

  std::vector<QuicTransportStream*> streams;
  for (int i = 0; i < 10; i++) {
    QuicTransportStream* stream =
        client_->session()->OpenOutgoingUnidirectionalStream();
    ASSERT_TRUE(stream->Write("test"));
    streams.push_back(stream);
  }
  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
      [this]() {
        return server_->session()->GetNumOpenIncomingStreams() == 10;
      },
      kDefaultTimeout));

  for (QuicTransportStream* stream : streams) {
    ASSERT_TRUE(stream->SendFin());
  }
  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
      [this]() { return server_->session()->GetNumOpenIncomingStreams() == 0; },
      kDefaultTimeout));
}

TEST_F(QuicTransportIntegrationTest, EchoBidirectionalStreams) {
  CreateDefaultEndpoints("/echo");
  WireUpEndpoints();
  RunHandshake();

  QuicTransportStream* stream =
      client_->session()->OpenOutgoingBidirectionalStream();
  EXPECT_TRUE(stream->Write("Hello!"));

  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
      [stream]() { return stream->ReadableBytes() == strlen("Hello!"); },
      kDefaultTimeout));
  std::string received;
  EXPECT_EQ(stream->Read(&received), strlen("Hello!"));
  EXPECT_EQ(received, "Hello!");

  EXPECT_TRUE(stream->SendFin());
  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
      [this]() { return server_->session()->GetNumOpenIncomingStreams() == 0; },
      kDefaultTimeout));
}

TEST_F(QuicTransportIntegrationTest, EchoUnidirectionalStreams) {
  CreateDefaultEndpoints("/echo");
  WireUpEndpoints();
  RunHandshake();

  // Send two streams, but only send FIN on the second one.
  QuicTransportStream* stream1 =
      client_->session()->OpenOutgoingUnidirectionalStream();
  EXPECT_TRUE(stream1->Write("Stream One"));
  QuicTransportStream* stream2 =
      client_->session()->OpenOutgoingUnidirectionalStream();
  EXPECT_TRUE(stream2->Write("Stream Two"));
  EXPECT_TRUE(stream2->SendFin());

  // Wait until a stream is received.
  bool stream_received = false;
  EXPECT_CALL(*client_->visitor(), OnIncomingUnidirectionalStreamAvailable())
      .Times(2)
      .WillRepeatedly(Assign(&stream_received, true));
  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
      [&stream_received]() { return stream_received; }, kDefaultTimeout));

  // Receive a reply stream and expect it to be the second one.
  QuicTransportStream* reply =
      client_->session()->AcceptIncomingUnidirectionalStream();
  ASSERT_TRUE(reply != nullptr);
  std::string buffer;
  reply->set_visitor(VisitorExpectingFin());
  EXPECT_GT(reply->Read(&buffer), 0u);
  EXPECT_EQ(buffer, "Stream Two");

  // Reset reply-related variables.
  stream_received = false;
  buffer = "";

  // Send FIN on the first stream, and expect to receive it back.
  EXPECT_TRUE(stream1->SendFin());
  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
      [&stream_received]() { return stream_received; }, kDefaultTimeout));
  reply = client_->session()->AcceptIncomingUnidirectionalStream();
  ASSERT_TRUE(reply != nullptr);
  reply->set_visitor(VisitorExpectingFin());
  EXPECT_GT(reply->Read(&buffer), 0u);
  EXPECT_EQ(buffer, "Stream One");
}

TEST_F(QuicTransportIntegrationTest, EchoDatagram) {
  CreateDefaultEndpoints("/echo");
  WireUpEndpoints();
  RunHandshake();

  client_->session()->datagram_queue()->SendOrQueueDatagram(
      MemSliceFromString("test"));

  bool datagram_received = false;
  EXPECT_CALL(*client_->visitor(), OnIncomingDatagramAvailable())
      .WillOnce(Assign(&datagram_received, true));
  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
      [&datagram_received]() { return datagram_received; }, kDefaultTimeout));

  QuicOptional<std::string> datagram = client_->session()->ReadDatagram();
  ASSERT_TRUE(datagram.has_value());
  EXPECT_EQ("test", *datagram);
}

// This test sets the datagram queue to an nearly-infinte queueing time, and
// then sends 1000 datagrams.  We expect to receive most of them back, since the
// datagrams would be paced out by the congestion controller.
TEST_F(QuicTransportIntegrationTest, EchoALotOfDatagrams) {
  CreateDefaultEndpoints("/echo");
  WireUpEndpoints();
  RunHandshake();

  // Set the datagrams to effectively never expire.
  client_->session()->datagram_queue()->SetMaxTimeInQueue(10000 * kRtt);
  for (int i = 0; i < 1000; i++) {
    client_->session()->datagram_queue()->SendOrQueueDatagram(
        MemSliceFromString(std::string(
            client_->session()->GetGuaranteedLargestMessagePayload(), 'a')));
  }

  size_t received = 0;
  EXPECT_CALL(*client_->visitor(), OnIncomingDatagramAvailable())
      .WillRepeatedly([this, &received]() {
        while (client_->session()->ReadDatagram().has_value()) {
          received++;
        }
      });
  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
      [this]() { return client_->session()->datagram_queue()->empty(); },
      3 * kServerBandwidth.TransferTime(1000 * kMaxOutgoingPacketSize)));
  // Allow extra round-trips for the final flight of datagrams to arrive back.
  simulator_.RunFor(2 * kRtt);

  EXPECT_GT(received, 500u);
  EXPECT_LT(received, 1000u);
}

TEST_F(QuicTransportIntegrationTest, OutgoingStreamFlowControlBlocked) {
  server_config_.SetMaxUnidirectionalStreamsToSend(4);
  CreateDefaultEndpoints("/discard");
  WireUpEndpoints();
  RunHandshake();

  QuicTransportStream* stream;
  // Note that since we've already used one stream for client indication, we can
  // only send three streams at once.
  for (int i = 0; i < 3; i++) {
    ASSERT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
    stream = client_->session()->OpenOutgoingUnidirectionalStream();
    ASSERT_TRUE(stream != nullptr);
    ASSERT_TRUE(stream->SendFin());
  }
  EXPECT_FALSE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());

  // Receiving FINs for the streams we've just opened will cause the server to
  // let us open more streams.
  bool can_create_new_stream = false;
  EXPECT_CALL(*client_->visitor(), OnCanCreateNewOutgoingUnidirectionalStream())
      .WillOnce(Assign(&can_create_new_stream, true));
  ASSERT_TRUE(simulator_.RunUntilOrTimeout(
      [&can_create_new_stream]() { return can_create_new_stream; },
      kDefaultTimeout));
  EXPECT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream());
}

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