// Copyright (c) 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 "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h"

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"

using testing::StrictMock;

namespace quic {
namespace test {
namespace {

class MockDelegate : public QpackDecoderStreamReceiver::Delegate {
 public:
  ~MockDelegate() override = default;

  MOCK_METHOD1(OnTableStateSynchronize, void(uint64_t insert_count));
  MOCK_METHOD1(OnHeaderAcknowledgement, void(QuicStreamId stream_id));
  MOCK_METHOD1(OnStreamCancellation, void(QuicStreamId stream_id));
  MOCK_METHOD1(OnErrorDetected, void(QuicStringPiece error_message));
};

class QpackDecoderStreamReceiverTest : public QuicTest {
 protected:
  QpackDecoderStreamReceiverTest() : stream_(&delegate_) {}
  ~QpackDecoderStreamReceiverTest() override = default;

  QpackDecoderStreamReceiver stream_;
  StrictMock<MockDelegate> delegate_;
};

TEST_F(QpackDecoderStreamReceiverTest, TableStateSynchronize) {
  EXPECT_CALL(delegate_, OnTableStateSynchronize(0));
  stream_.Decode(QuicTextUtils::HexDecode("00"));

  EXPECT_CALL(delegate_, OnTableStateSynchronize(10));
  stream_.Decode(QuicTextUtils::HexDecode("0a"));

  EXPECT_CALL(delegate_, OnTableStateSynchronize(63));
  stream_.Decode(QuicTextUtils::HexDecode("3f00"));

  EXPECT_CALL(delegate_, OnTableStateSynchronize(200));
  stream_.Decode(QuicTextUtils::HexDecode("3f8901"));

  EXPECT_CALL(delegate_, OnErrorDetected("Encoded integer too large."));
  stream_.Decode(QuicTextUtils::HexDecode("3fffffffffffffffffffff"));
}

TEST_F(QpackDecoderStreamReceiverTest, HeaderAcknowledgement) {
  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(0));
  stream_.Decode(QuicTextUtils::HexDecode("80"));

  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(37));
  stream_.Decode(QuicTextUtils::HexDecode("a5"));

  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(127));
  stream_.Decode(QuicTextUtils::HexDecode("ff00"));

  EXPECT_CALL(delegate_, OnHeaderAcknowledgement(503));
  stream_.Decode(QuicTextUtils::HexDecode("fff802"));

  EXPECT_CALL(delegate_, OnErrorDetected("Encoded integer too large."));
  stream_.Decode(QuicTextUtils::HexDecode("ffffffffffffffffffffff"));
}

TEST_F(QpackDecoderStreamReceiverTest, StreamCancellation) {
  EXPECT_CALL(delegate_, OnStreamCancellation(0));
  stream_.Decode(QuicTextUtils::HexDecode("40"));

  EXPECT_CALL(delegate_, OnStreamCancellation(19));
  stream_.Decode(QuicTextUtils::HexDecode("53"));

  EXPECT_CALL(delegate_, OnStreamCancellation(63));
  stream_.Decode(QuicTextUtils::HexDecode("7f00"));

  EXPECT_CALL(delegate_, OnStreamCancellation(110));
  stream_.Decode(QuicTextUtils::HexDecode("7f2f"));

  EXPECT_CALL(delegate_, OnErrorDetected("Encoded integer too large."));
  stream_.Decode(QuicTextUtils::HexDecode("7fffffffffffffffffffff"));
}

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