// 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_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_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));

    SetQuicReloadableFlag(quic_supports_tls_handshake, true);
  }
};

class QuicTransportClientEndpoint : public QuicTransportEndpointBase {
 public:
  QuicTransportClientEndpoint(Simulator* simulator,
                              const std::string& name,
                              const std::string& peer_name,
                              url::Origin origin)
      : QuicTransportEndpointBase(simulator,
                                  name,
                                  peer_name,
                                  Perspective::IS_CLIENT),
        crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
        session_(connection_.get(),
                 nullptr,
                 DefaultQuicConfig(),
                 GetVersions(),
                 QuicServerId("test.example.com", 443),
                 &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,
                              QuicTransportSimpleServerSession::Mode mode,
                              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,
                 DefaultQuicConfig(),
                 GetVersions(),
                 &crypto_config_,
                 &compressed_certs_cache_,
                 mode,
                 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(QuicTransportSimpleServerSession::Mode mode) {
    client_ = std::make_unique<QuicTransportClientEndpoint>(
        &simulator_, "Client", "Server", GetTestOrigin());
    server_ = std::make_unique<QuicTransportServerEndpoint>(
        &simulator_, "Server", "Client", mode, 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;
  }

  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(QuicTransportSimpleServerSession::DISCARD);
  WireUpEndpoints();
  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(QuicTransportSimpleServerSession::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(QuicTransportSimpleServerSession::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(QuicTransportSimpleServerSession::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(QuicTransportSimpleServerSession::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");
}

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