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

#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h"

#include <memory>
#include <utility>

#include "url/gurl.h"
#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.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/common/platform/api/quiche_arraysize.h"

namespace quic {
namespace test {
namespace {

using testing::_;
using testing::ElementsAre;
using testing::Eq;

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

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

std::string DataInStream(QuicStream* stream) {
  QuicStreamSendBuffer& send_buffer = QuicStreamPeer::SendBuffer(stream);
  std::string result;
  result.resize(send_buffer.stream_offset());
  QuicDataWriter writer(result.size(), &result[0]);
  EXPECT_TRUE(
      send_buffer.WriteStreamData(0, send_buffer.stream_offset(), &writer));
  return result;
}

class QuicTransportClientSessionTest : public QuicTest {
 protected:
  QuicTransportClientSessionTest()
      : connection_(&helper_,
                    &alarm_factory_,
                    Perspective::IS_CLIENT,
                    GetVersions()),
        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
    CreateSession(GetTestOrigin(), "");
  }

  void CreateSession(url::Origin origin, std::string url_suffix) {
    session_ = std::make_unique<QuicTransportClientSession>(
        &connection_, nullptr, DefaultQuicConfig(), GetVersions(),
        GURL("quic-transport://test.example.com:50000" + url_suffix),
        &crypto_config_, origin, &visitor_);
    session_->Initialize();
    crypto_stream_ = static_cast<QuicCryptoClientStream*>(
        session_->GetMutableCryptoStream());
  }

  void Connect() {
    session_->CryptoConnect();
    QuicConfig server_config = DefaultQuicConfig();
    std::unique_ptr<QuicCryptoServerConfig> crypto_config(
        crypto_test_utils::CryptoServerConfigForTesting());
    crypto_test_utils::HandshakeWithFakeServer(
        &server_config, crypto_config.get(), &helper_, &alarm_factory_,
        &connection_, crypto_stream_, QuicTransportAlpn());
  }

  MockAlarmFactory alarm_factory_;
  MockQuicConnectionHelper helper_;

  PacketSavingConnection connection_;
  QuicCryptoClientConfig crypto_config_;
  MockClientVisitor visitor_;
  std::unique_ptr<QuicTransportClientSession> session_;
  QuicCryptoClientStream* crypto_stream_;
};

TEST_F(QuicTransportClientSessionTest, HasValidAlpn) {
  EXPECT_THAT(session_->GetAlpnsToOffer(), ElementsAre(QuicTransportAlpn()));
}

TEST_F(QuicTransportClientSessionTest, SuccessfulConnection) {
  constexpr char kTestOriginClientIndication[] =
      "\0\0"                      // key (0x0000, origin)
      "\0\x18"                    // length
      "https://test-origin.test"  // value
      "\0\x01"                    // key (0x0001, path)
      "\0\x01"                    // length
      "/";                        // value

  EXPECT_CALL(visitor_, OnSessionReady());
  Connect();
  EXPECT_TRUE(session_->IsSessionReady());

  QuicStream* client_indication_stream =
      QuicSessionPeer::zombie_streams(session_.get())[ClientIndicationStream()]
          .get();
  ASSERT_TRUE(client_indication_stream != nullptr);
  const std::string client_indication = DataInStream(client_indication_stream);
  const std::string expected_client_indication{
      kTestOriginClientIndication,
      QUICHE_ARRAYSIZE(kTestOriginClientIndication) - 1};
  EXPECT_EQ(client_indication, expected_client_indication);
}

TEST_F(QuicTransportClientSessionTest, SuccessfulConnectionWithPath) {
  constexpr char kSuffix[] = "/foo/bar?hello=world#not-sent";
  constexpr char kTestOriginClientIndication[] =
      "\0\0"                      // key (0x0000, origin)
      "\0\x18"                    // length
      "https://test-origin.test"  // value
      "\0\x01"                    // key (0x0001, path)
      "\0\x14"                    // length
      "/foo/bar?hello=world";     // value

  CreateSession(GetTestOrigin(), kSuffix);
  Connect();
  EXPECT_TRUE(session_->IsSessionReady());

  QuicStream* client_indication_stream =
      QuicSessionPeer::zombie_streams(session_.get())[ClientIndicationStream()]
          .get();
  ASSERT_TRUE(client_indication_stream != nullptr);
  const std::string client_indication = DataInStream(client_indication_stream);
  const std::string expected_client_indication{
      kTestOriginClientIndication,
      QUICHE_ARRAYSIZE(kTestOriginClientIndication) - 1};
  EXPECT_EQ(client_indication, expected_client_indication);
}

TEST_F(QuicTransportClientSessionTest, OriginTooLong) {
  std::string long_string(68000, 'a');
  GURL bad_origin_url{"https://" + long_string + ".example/"};
  EXPECT_TRUE(bad_origin_url.is_valid());
  CreateSession(url::Origin::Create(bad_origin_url), "");

  EXPECT_QUIC_BUG(Connect(), "Client origin too long");
}

TEST_F(QuicTransportClientSessionTest, ReceiveNewStreams) {
  Connect();
  ASSERT_TRUE(session_->IsSessionReady());
  ASSERT_TRUE(session_->AcceptIncomingUnidirectionalStream() == nullptr);

  const QuicStreamId id = GetNthServerInitiatedUnidirectionalStreamId(
      session_->transport_version(), 0);
  QuicStreamFrame frame(id, /*fin=*/false, /*offset=*/0, "test");
  EXPECT_CALL(visitor_, OnIncomingUnidirectionalStreamAvailable()).Times(1);
  session_->OnStreamFrame(frame);

  QuicTransportStream* stream = session_->AcceptIncomingUnidirectionalStream();
  ASSERT_TRUE(stream != nullptr);
  EXPECT_EQ(stream->ReadableBytes(), 4u);
  EXPECT_EQ(stream->id(), id);
}

TEST_F(QuicTransportClientSessionTest, ReceiveDatagram) {
  EXPECT_CALL(visitor_, OnDatagramReceived(Eq("test")));
  session_->OnMessageReceived("test");
}

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