// Copyright (c) 2016 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 "quiche/quic/core/chlo_extractor.h"

#include <memory>
#include <string>
#include <utility>

#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/quic_framer.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/crypto_test_utils.h"
#include "quiche/quic/test_tools/first_flight.h"
#include "quiche/quic/test_tools/quic_test_utils.h"

namespace quic {
namespace test {
namespace {

class TestDelegate : public ChloExtractor::Delegate {
 public:
  TestDelegate() = default;
  ~TestDelegate() override = default;

  // ChloExtractor::Delegate implementation
  void OnChlo(QuicTransportVersion version, QuicConnectionId connection_id,
              const CryptoHandshakeMessage& chlo) override {
    version_ = version;
    connection_id_ = connection_id;
    chlo_ = chlo.DebugString();
    absl::string_view alpn_value;
    if (chlo.GetStringPiece(kALPN, &alpn_value)) {
      alpn_ = std::string(alpn_value);
    }
  }

  QuicConnectionId connection_id() const { return connection_id_; }
  QuicTransportVersion transport_version() const { return version_; }
  const std::string& chlo() const { return chlo_; }
  const std::string& alpn() const { return alpn_; }

 private:
  QuicConnectionId connection_id_;
  QuicTransportVersion version_;
  std::string chlo_;
  std::string alpn_;
};

class ChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
 public:
  ChloExtractorTest() : version_(GetParam()) {}

  void MakePacket(absl::string_view data, bool munge_offset,
                  bool munge_stream_id) {
    QuicPacketHeader header;
    header.destination_connection_id = TestConnectionId();
    header.destination_connection_id_included = CONNECTION_ID_PRESENT;
    header.version_flag = true;
    header.version = version_;
    header.reset_flag = false;
    header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
    header.packet_number = QuicPacketNumber(1);
    if (version_.HasLongHeaderLengths()) {
      header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
      header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
    }
    QuicFrames frames;
    size_t offset = 0;
    if (munge_offset) {
      offset++;
    }
    QuicFramer framer(SupportedVersions(version_), QuicTime::Zero(),
                      Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
    framer.SetInitialObfuscators(TestConnectionId());
    if (!version_.UsesCryptoFrames() || munge_stream_id) {
      QuicStreamId stream_id =
          QuicUtils::GetCryptoStreamId(version_.transport_version);
      if (munge_stream_id) {
        stream_id++;
      }
      frames.push_back(
          QuicFrame(QuicStreamFrame(stream_id, false, offset, data)));
    } else {
      frames.push_back(
          QuicFrame(new QuicCryptoFrame(ENCRYPTION_INITIAL, offset, data)));
    }
    std::unique_ptr<QuicPacket> packet(
        BuildUnsizedDataPacket(&framer, header, frames));
    EXPECT_TRUE(packet != nullptr);
    size_t encrypted_length =
        framer.EncryptPayload(ENCRYPTION_INITIAL, header.packet_number, *packet,
                              buffer_, ABSL_ARRAYSIZE(buffer_));
    ASSERT_NE(0u, encrypted_length);
    packet_ = std::make_unique<QuicEncryptedPacket>(buffer_, encrypted_length);
    EXPECT_TRUE(packet_ != nullptr);
    DeleteFrames(&frames);
  }

 protected:
  ParsedQuicVersion version_;
  TestDelegate delegate_;
  std::unique_ptr<QuicEncryptedPacket> packet_;
  char buffer_[kMaxOutgoingPacketSize];
};

INSTANTIATE_TEST_SUITE_P(
    ChloExtractorTests, ChloExtractorTest,
    ::testing::ValuesIn(AllSupportedVersionsWithQuicCrypto()),
    ::testing::PrintToStringParamName());

TEST_P(ChloExtractorTest, FindsValidChlo) {
  CryptoHandshakeMessage client_hello;
  client_hello.set_tag(kCHLO);

  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());

  MakePacket(client_hello_str, /*munge_offset=*/false,
             /*munge_stream_id=*/false);
  EXPECT_TRUE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
                                     kQuicDefaultConnectionIdLength));
  EXPECT_EQ(version_.transport_version, delegate_.transport_version());
  EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
  EXPECT_EQ(client_hello.DebugString(), delegate_.chlo());
}

TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongStream) {
  if (version_.UsesCryptoFrames()) {
    // When crypto frames are in use we do not use stream frames.
    return;
  }
  CryptoHandshakeMessage client_hello;
  client_hello.set_tag(kCHLO);

  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
  MakePacket(client_hello_str,
             /*munge_offset=*/false, /*munge_stream_id=*/true);
  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
                                      kQuicDefaultConnectionIdLength));
}

TEST_P(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) {
  CryptoHandshakeMessage client_hello;
  client_hello.set_tag(kCHLO);

  std::string client_hello_str(client_hello.GetSerialized().AsStringPiece());
  MakePacket(client_hello_str, /*munge_offset=*/true,
             /*munge_stream_id=*/false);
  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
                                      kQuicDefaultConnectionIdLength));
}

TEST_P(ChloExtractorTest, DoesNotFindInvalidChlo) {
  MakePacket("foo", /*munge_offset=*/false,
             /*munge_stream_id=*/false);
  EXPECT_FALSE(ChloExtractor::Extract(*packet_, version_, {}, &delegate_,
                                      kQuicDefaultConnectionIdLength));
}

TEST_P(ChloExtractorTest, FirstFlight) {
  std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
      GetFirstFlightOfPackets(version_);
  ASSERT_EQ(packets.size(), 1u);
  EXPECT_TRUE(ChloExtractor::Extract(*packets[0], version_, {}, &delegate_,
                                     kQuicDefaultConnectionIdLength));
  EXPECT_EQ(version_.transport_version, delegate_.transport_version());
  EXPECT_EQ(TestConnectionId(), delegate_.connection_id());
  EXPECT_EQ(AlpnForVersion(version_), delegate_.alpn());
}

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