// Copyright 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 "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_decoder.h"

// Tests of HpackHuffmanDecoder and HuffmanBitBuffer.

#include <iostream>

#include "net/third_party/quiche/src/http2/decoder/decode_buffer.h"
#include "net/third_party/quiche/src/http2/decoder/decode_status.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h"
#include "net/third_party/quiche/src/http2/tools/random_decoder_test.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_test.h"

using ::testing::AssertionResult;

namespace http2 {
namespace test {
namespace {

TEST(HuffmanBitBufferTest, Reset) {
  HuffmanBitBuffer bb;
  EXPECT_TRUE(bb.IsEmpty());
  EXPECT_TRUE(bb.InputProperlyTerminated());
  EXPECT_EQ(bb.count(), 0u);
  EXPECT_EQ(bb.free_count(), 64u);
  EXPECT_EQ(bb.value(), 0u);
}

TEST(HuffmanBitBufferTest, AppendBytesAligned) {
  std::string s;
  s.push_back('\x11');
  s.push_back('\x22');
  s.push_back('\x33');
  quiche::QuicheStringPiece sp(s);

  HuffmanBitBuffer bb;
  sp.remove_prefix(bb.AppendBytes(sp));
  EXPECT_TRUE(sp.empty());
  EXPECT_FALSE(bb.IsEmpty()) << bb;
  EXPECT_FALSE(bb.InputProperlyTerminated());
  EXPECT_EQ(bb.count(), 24u) << bb;
  EXPECT_EQ(bb.free_count(), 40u) << bb;
  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x112233) << 40) << bb;

  s.clear();
  s.push_back('\x44');
  sp = s;

  sp.remove_prefix(bb.AppendBytes(sp));
  EXPECT_TRUE(sp.empty());
  EXPECT_EQ(bb.count(), 32u) << bb;
  EXPECT_EQ(bb.free_count(), 32u) << bb;
  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x11223344) << 32) << bb;

  s.clear();
  s.push_back('\x55');
  s.push_back('\x66');
  s.push_back('\x77');
  s.push_back('\x88');
  s.push_back('\x99');
  sp = s;

  sp.remove_prefix(bb.AppendBytes(sp));
  EXPECT_EQ(sp.size(), 1u);
  EXPECT_EQ('\x99', sp[0]);
  EXPECT_EQ(bb.count(), 64u) << bb;
  EXPECT_EQ(bb.free_count(), 0u) << bb;
  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x1122334455667788LL)) << bb;

  sp.remove_prefix(bb.AppendBytes(sp));
  EXPECT_EQ(sp.size(), 1u);
  EXPECT_EQ('\x99', sp[0]);
  EXPECT_EQ(bb.count(), 64u) << bb;
  EXPECT_EQ(bb.free_count(), 0u) << bb;
  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x1122334455667788LL)) << bb;
}

TEST(HuffmanBitBufferTest, ConsumeBits) {
  std::string s;
  s.push_back('\x11');
  s.push_back('\x22');
  s.push_back('\x33');
  quiche::QuicheStringPiece sp(s);

  HuffmanBitBuffer bb;
  sp.remove_prefix(bb.AppendBytes(sp));
  EXPECT_TRUE(sp.empty());

  bb.ConsumeBits(1);
  EXPECT_EQ(bb.count(), 23u) << bb;
  EXPECT_EQ(bb.free_count(), 41u) << bb;
  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x112233) << 41) << bb;

  bb.ConsumeBits(20);
  EXPECT_EQ(bb.count(), 3u) << bb;
  EXPECT_EQ(bb.free_count(), 61u) << bb;
  EXPECT_EQ(bb.value(), HuffmanAccumulator(0x3) << 61) << bb;
}

TEST(HuffmanBitBufferTest, AppendBytesUnaligned) {
  std::string s;
  s.push_back('\x11');
  s.push_back('\x22');
  s.push_back('\x33');
  s.push_back('\x44');
  s.push_back('\x55');
  s.push_back('\x66');
  s.push_back('\x77');
  s.push_back('\x88');
  s.push_back('\x99');
  s.push_back('\xaa');
  s.push_back('\xbb');
  s.push_back('\xcc');
  s.push_back('\xdd');
  quiche::QuicheStringPiece sp(s);

  HuffmanBitBuffer bb;
  sp.remove_prefix(bb.AppendBytes(sp));
  EXPECT_EQ(sp.size(), 5u);
  EXPECT_FALSE(bb.InputProperlyTerminated());

  bb.ConsumeBits(15);
  EXPECT_EQ(bb.count(), 49u) << bb;
  EXPECT_EQ(bb.free_count(), 15u) << bb;

  HuffmanAccumulator expected(0x1122334455667788);
  expected <<= 15;
  EXPECT_EQ(bb.value(), expected);

  sp.remove_prefix(bb.AppendBytes(sp));
  EXPECT_EQ(sp.size(), 4u);
  EXPECT_EQ(bb.count(), 57u) << bb;
  EXPECT_EQ(bb.free_count(), 7u) << bb;

  expected |= (HuffmanAccumulator(0x99) << 7);
  EXPECT_EQ(bb.value(), expected)
      << bb << std::hex << "\n   actual: " << bb.value()
      << "\n expected: " << expected;
}

class HpackHuffmanDecoderTest : public RandomDecoderTest {
 protected:
  HpackHuffmanDecoderTest() {
    // The decoder may return true, and its accumulator may be empty, at
    // many boundaries while decoding, and yet the whole string hasn't
    // been decoded.
    stop_decode_on_done_ = false;
  }

  DecodeStatus StartDecoding(DecodeBuffer* b) override {
    input_bytes_seen_ = 0;
    output_buffer_.clear();
    decoder_.Reset();
    return ResumeDecoding(b);
  }

  DecodeStatus ResumeDecoding(DecodeBuffer* b) override {
    input_bytes_seen_ += b->Remaining();
    quiche::QuicheStringPiece sp(b->cursor(), b->Remaining());
    if (decoder_.Decode(sp, &output_buffer_)) {
      b->AdvanceCursor(b->Remaining());
      // Successfully decoded (or buffered) the bytes in QuicheStringPiece.
      EXPECT_LE(input_bytes_seen_, input_bytes_expected_);
      // Have we reached the end of the encoded string?
      if (input_bytes_expected_ == input_bytes_seen_) {
        if (decoder_.InputProperlyTerminated()) {
          return DecodeStatus::kDecodeDone;
        } else {
          return DecodeStatus::kDecodeError;
        }
      }
      return DecodeStatus::kDecodeInProgress;
    }
    return DecodeStatus::kDecodeError;
  }

  HpackHuffmanDecoder decoder_;
  std::string output_buffer_;
  size_t input_bytes_seen_;
  size_t input_bytes_expected_;
};

TEST_F(HpackHuffmanDecoderTest, SpecRequestExamples) {
  HpackHuffmanDecoder decoder;
  std::string test_table[] = {
      Http2HexDecode("f1e3c2e5f23a6ba0ab90f4ff"),
      "www.example.com",
      Http2HexDecode("a8eb10649cbf"),
      "no-cache",
      Http2HexDecode("25a849e95ba97d7f"),
      "custom-key",
      Http2HexDecode("25a849e95bb8e8b4bf"),
      "custom-value",
  };
  for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); i += 2) {
    const std::string& huffman_encoded(test_table[i]);
    const std::string& plain_string(test_table[i + 1]);
    std::string buffer;
    decoder.Reset();
    EXPECT_TRUE(decoder.Decode(huffman_encoded, &buffer)) << decoder;
    EXPECT_TRUE(decoder.InputProperlyTerminated()) << decoder;
    EXPECT_EQ(buffer, plain_string);
  }
}

TEST_F(HpackHuffmanDecoderTest, SpecResponseExamples) {
  HpackHuffmanDecoder decoder;
  // clang-format off
  std::string test_table[] = {
    Http2HexDecode("6402"),
    "302",
    Http2HexDecode("aec3771a4b"),
    "private",
    Http2HexDecode("d07abe941054d444a8200595040b8166"
            "e082a62d1bff"),
    "Mon, 21 Oct 2013 20:13:21 GMT",
    Http2HexDecode("9d29ad171863c78f0b97c8e9ae82ae43"
            "d3"),
    "https://www.example.com",
    Http2HexDecode("94e7821dd7f2e6c7b335dfdfcd5b3960"
            "d5af27087f3672c1ab270fb5291f9587"
            "316065c003ed4ee5b1063d5007"),
    "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
  };
  // clang-format on
  for (size_t i = 0; i != QUICHE_ARRAYSIZE(test_table); i += 2) {
    const std::string& huffman_encoded(test_table[i]);
    const std::string& plain_string(test_table[i + 1]);
    std::string buffer;
    decoder.Reset();
    EXPECT_TRUE(decoder.Decode(huffman_encoded, &buffer)) << decoder;
    EXPECT_TRUE(decoder.InputProperlyTerminated()) << decoder;
    EXPECT_EQ(buffer, plain_string);
  }
}

}  // namespace
}  // namespace test
}  // namespace http2
