// Copyright 2018 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/qpack/qpack_instruction_decoder.h"

#include <algorithm>

#include "absl/strings/escaping.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/qpack/qpack_instructions.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/qpack/qpack_test_utils.h"

using ::testing::_;
using ::testing::Eq;
using ::testing::Expectation;
using ::testing::InvokeWithoutArgs;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::Values;

namespace quic {
namespace test {
namespace {

// This instruction has three fields: an S bit and two varints.
const QpackInstruction* TestInstruction1() {
  static const QpackInstruction* const instruction =
      new QpackInstruction{QpackInstructionOpcode{0x00, 0x80},
                           {{QpackInstructionFieldType::kSbit, 0x40},
                            {QpackInstructionFieldType::kVarint, 6},
                            {QpackInstructionFieldType::kVarint2, 8}}};
  return instruction;
}

// This instruction has two fields: a header name with a 6-bit prefix, and a
// header value with a 7-bit prefix, both preceded by a Huffman bit.
const QpackInstruction* TestInstruction2() {
  static const QpackInstruction* const instruction =
      new QpackInstruction{QpackInstructionOpcode{0x80, 0x80},
                           {{QpackInstructionFieldType::kName, 6},
                            {QpackInstructionFieldType::kValue, 7}}};
  return instruction;
}

const QpackLanguage* TestLanguage() {
  static const QpackLanguage* const language =
      new QpackLanguage{TestInstruction1(), TestInstruction2()};
  return language;
}

class MockDelegate : public QpackInstructionDecoder::Delegate {
 public:
  MockDelegate() {
    ON_CALL(*this, OnInstructionDecoded(_)).WillByDefault(Return(true));
  }

  MockDelegate(const MockDelegate&) = delete;
  MockDelegate& operator=(const MockDelegate&) = delete;
  ~MockDelegate() override = default;

  MOCK_METHOD(bool, OnInstructionDecoded, (const QpackInstruction*),
              (override));
  MOCK_METHOD(void, OnInstructionDecodingError,
              (QpackInstructionDecoder::ErrorCode error_code,
               absl::string_view error_message),
              (override));
};

class QpackInstructionDecoderTest : public QuicTestWithParam<FragmentMode> {
 protected:
  QpackInstructionDecoderTest()
      : decoder_(std::make_unique<QpackInstructionDecoder>(TestLanguage(),
                                                           &delegate_)),
        fragment_mode_(GetParam()) {}
  ~QpackInstructionDecoderTest() override = default;

  void SetUp() override {
    // Destroy QpackInstructionDecoder on error to test that it does not crash.
    // See https://crbug.com/1025209.
    ON_CALL(delegate_, OnInstructionDecodingError(_, _))
        .WillByDefault(InvokeWithoutArgs([this]() { decoder_.reset(); }));
  }

  // Decode one full instruction with fragment sizes dictated by
  // |fragment_mode_|.
  // Assumes that |data| is a single complete instruction, and accordingly
  // verifies that AtInstructionBoundary() returns true before and after the
  // instruction, and returns false while decoding is in progress.
  // Assumes that delegate methods destroy |decoder_| if they return false.
  void DecodeInstruction(absl::string_view data) {
    EXPECT_TRUE(decoder_->AtInstructionBoundary());

    FragmentSizeGenerator fragment_size_generator =
        FragmentModeToFragmentSizeGenerator(fragment_mode_);

    while (!data.empty()) {
      size_t fragment_size = std::min(fragment_size_generator(), data.size());
      bool success = decoder_->Decode(data.substr(0, fragment_size));
      if (!decoder_) {
        EXPECT_FALSE(success);
        return;
      }
      EXPECT_TRUE(success);
      data = data.substr(fragment_size);
      if (!data.empty()) {
        EXPECT_FALSE(decoder_->AtInstructionBoundary());
      }
    }

    EXPECT_TRUE(decoder_->AtInstructionBoundary());
  }

  StrictMock<MockDelegate> delegate_;
  std::unique_ptr<QpackInstructionDecoder> decoder_;

 private:
  const FragmentMode fragment_mode_;
};

INSTANTIATE_TEST_SUITE_P(All, QpackInstructionDecoderTest,
                         Values(FragmentMode::kSingleChunk,
                                FragmentMode::kOctetByOctet));

TEST_P(QpackInstructionDecoderTest, SBitAndVarint2) {
  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
  DecodeInstruction(absl::HexStringToBytes("7f01ff65"));

  EXPECT_TRUE(decoder_->s_bit());
  EXPECT_EQ(64u, decoder_->varint());
  EXPECT_EQ(356u, decoder_->varint2());

  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
  DecodeInstruction(absl::HexStringToBytes("05c8"));

  EXPECT_FALSE(decoder_->s_bit());
  EXPECT_EQ(5u, decoder_->varint());
  EXPECT_EQ(200u, decoder_->varint2());
}

TEST_P(QpackInstructionDecoderTest, NameAndValue) {
  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
  DecodeInstruction(absl::HexStringToBytes("83666f6f03626172"));

  EXPECT_EQ("foo", decoder_->name());
  EXPECT_EQ("bar", decoder_->value());

  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
  DecodeInstruction(absl::HexStringToBytes("8000"));

  EXPECT_EQ("", decoder_->name());
  EXPECT_EQ("", decoder_->value());

  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
  DecodeInstruction(absl::HexStringToBytes("c294e7838c767f"));

  EXPECT_EQ("foo", decoder_->name());
  EXPECT_EQ("bar", decoder_->value());
}

TEST_P(QpackInstructionDecoderTest, InvalidHuffmanEncoding) {
  EXPECT_CALL(delegate_,
              OnInstructionDecodingError(
                  QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR,
                  Eq("Error in Huffman-encoded string.")));
  DecodeInstruction(absl::HexStringToBytes("c1ff"));
}

TEST_P(QpackInstructionDecoderTest, InvalidVarintEncoding) {
  EXPECT_CALL(delegate_,
              OnInstructionDecodingError(
                  QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE,
                  Eq("Encoded integer too large.")));
  DecodeInstruction(absl::HexStringToBytes("ffffffffffffffffffffff"));
}

TEST_P(QpackInstructionDecoderTest, StringLiteralTooLong) {
  EXPECT_CALL(delegate_,
              OnInstructionDecodingError(
                  QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG,
                  Eq("String literal too long.")));
  DecodeInstruction(absl::HexStringToBytes("bfffff7f"));
}

TEST_P(QpackInstructionDecoderTest, DelegateSignalsError) {
  // First instruction is valid.
  Expectation first_call =
      EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
          .WillOnce(InvokeWithoutArgs([this]() -> bool {
            EXPECT_EQ(1u, decoder_->varint());
            return true;
          }));

  // Second instruction is invalid.  Decoding must halt.
  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
      .After(first_call)
      .WillOnce(InvokeWithoutArgs([this]() -> bool {
        EXPECT_EQ(2u, decoder_->varint());
        return false;
      }));

  EXPECT_FALSE(
      decoder_->Decode(absl::HexStringToBytes("01000200030004000500")));
}

// QpackInstructionDecoder must not crash if it is destroyed from a
// Delegate::OnInstructionDecoded() call as long as it returns false.
TEST_P(QpackInstructionDecoderTest, DelegateSignalsErrorAndDestroysDecoder) {
  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
      .WillOnce(InvokeWithoutArgs([this]() -> bool {
        EXPECT_EQ(1u, decoder_->varint());
        decoder_.reset();
        return false;
      }));
  DecodeInstruction(absl::HexStringToBytes("0100"));
}

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