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

#ifndef QUICHE_HTTP2_TEST_TOOLS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
#define QUICHE_HTTP2_TEST_TOOLS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_

// Base class for testing concrete payload decoder classes.

#include <stddef.h>

#include <string>

#include "absl/strings/string_view.h"
#include "quiche/http2/decoder/decode_buffer.h"
#include "quiche/http2/decoder/decode_status.h"
#include "quiche/http2/decoder/frame_decoder_state.h"
#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
#include "quiche/http2/http2_constants.h"
#include "quiche/http2/http2_structures.h"
#include "quiche/http2/test_tools/frame_parts.h"
#include "quiche/http2/test_tools/http2_constants_test_util.h"
#include "quiche/http2/test_tools/http2_frame_builder.h"
#include "quiche/http2/test_tools/random_decoder_test_base.h"
#include "quiche/http2/test_tools/verify_macros.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_callbacks.h"

namespace http2 {
namespace test {

// Base class for tests of payload decoders. Below this there is a templated
// sub-class that adds a bunch of type specific features.
class QUICHE_NO_EXPORT PayloadDecoderBaseTest : public RandomDecoderTest {
 protected:
  PayloadDecoderBaseTest();

  // Virtual functions to be implemented by the test classes for the individual
  // payload decoders...

  // Start decoding the payload.
  virtual DecodeStatus StartDecodingPayload(DecodeBuffer* db) = 0;

  // Resume decoding the payload.
  virtual DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) = 0;

  // In support of ensuring that we're really accessing and updating the
  // decoder, prepare the decoder by, for example, overwriting the decoder.
  virtual void PreparePayloadDecoder() = 0;

  // Get the listener to be inserted into the FrameDecoderState, ready for
  // listening (e.g. reset if it is a FramePartsCollector).
  virtual Http2FrameDecoderListener* PrepareListener() = 0;

  // Record a frame header for use on each call to StartDecoding.
  void set_frame_header(const Http2FrameHeader& header) {
    EXPECT_EQ(0, InvalidFlagMaskForFrameType(header.type) & header.flags);
    if (!frame_header_is_set_ || frame_header_ != header) {
      QUICHE_VLOG(2) << "set_frame_header: " << frame_header_;
    }
    frame_header_ = header;
    frame_header_is_set_ = true;
  }

  FrameDecoderState* mutable_state() { return frame_decoder_state_.get(); }

  // Randomize the payload decoder, sets the payload decoder's frame_header_,
  // then start decoding the payload. Called by RandomDecoderTest. This method
  // is final so that we can always perform certain actions when
  // RandomDecoderTest starts the decoding of a payload, such as randomizing the
  // the payload decoder, injecting the frame header and counting fast decoding
  // cases. Sub-classes must implement StartDecodingPayload to perform their
  // initial decoding of a frame's payload.
  DecodeStatus StartDecoding(DecodeBuffer* db) final;

  // Called by RandomDecoderTest. This method is final so that we can always
  // perform certain actions when RandomDecoderTest calls it, such as counting
  // slow decode cases. Sub-classes must implement ResumeDecodingPayload to
  // continue decoding the frame's payload, which must not all be in one buffer.
  DecodeStatus ResumeDecoding(DecodeBuffer* db) final;

  // Given the specified payload (without the common frame header), decode
  // it with several partitionings of the payload.
  ::testing::AssertionResult DecodePayloadAndValidateSeveralWays(
      absl::string_view payload, Validator validator);

  // TODO(jamessynge): Add helper method for verifying these are both non-zero,
  // and call the new method from tests that expect successful decoding.
  void ResetDecodeSpeedCounters() {
    fast_decode_count_ = 0;
    slow_decode_count_ = 0;
  }

  // Count of payloads that are full decoded by StartDecodingPayload, or that
  // an error was detected by StartDecodingPayload.
  size_t fast_decode_count_ = 0;

  // Count of payloads that require calling ResumeDecodingPayload in order to
  // decode them completely (or to detect an error during decoding).
  size_t slow_decode_count_ = 0;

 private:
  bool frame_header_is_set_ = false;
  Http2FrameHeader frame_header_;
  std::unique_ptr<FrameDecoderState> frame_decoder_state_;
};

// Base class for payload decoders of type Decoder, with corresponding test
// peer of type DecoderPeer, and using class Listener as the implementation
// of Http2FrameDecoderListenerInterface to be used during decoding.
// Typically Listener is a sub-class of FramePartsCollector.
// SupportedFrameType is set to false only for UnknownPayloadDecoder.
template <class Decoder, class DecoderPeer, class Listener,
          bool SupportedFrameType = true>
class QUICHE_NO_EXPORT AbstractPayloadDecoderTest
    : public PayloadDecoderBaseTest {
 protected:
  // An ApproveSize function returns true to approve decoding the specified
  // size of payload, else false to skip that size. Typically used for negative
  // tests; for example, decoding a SETTINGS frame at all sizes except for
  // multiples of 6.
  typedef quiche::MultiUseCallback<bool(size_t size)> ApproveSize;

  AbstractPayloadDecoderTest() {}

  // These tests are in setup rather than the constructor for two reasons:
  // 1) Constructors are not allowed to fail, so gUnit documents that EXPECT_*
  //    and ASSERT_* are not allowed in constructors, and should instead be in
  //    SetUp if they are needed before the body of the test is executed.
  // 2) To allow the sub-class constructor to make any desired modifications to
  //    the DecoderPeer before these tests are executed; in particular,
  //    UnknownPayloadDecoderPeer has not got a fixed frame type, but it is
  //    instead set during the test's constructor.
  void SetUp() override {
    PayloadDecoderBaseTest::SetUp();

    // Confirm that DecoderPeer et al returns sensible values. Using auto as the
    // variable type so that no (narrowing) conversions take place that hide
    // problems; i.e. if someone changes KnownFlagsMaskForFrameType so that it
    // doesn't return a uint8, and has bits above the low-order 8 bits set, this
    // bit of paranoia should detect the problem before we get too far.
    auto frame_type = DecoderPeer::FrameType();
    if (SupportedFrameType) {
      EXPECT_TRUE(IsSupportedHttp2FrameType(frame_type)) << frame_type;
    } else {
      EXPECT_FALSE(IsSupportedHttp2FrameType(frame_type)) << frame_type;
    }

    auto known_flags = KnownFlagsMaskForFrameType(frame_type);
    EXPECT_EQ(known_flags, known_flags & 0xff);

    auto flags_to_avoid = DecoderPeer::FlagsAffectingPayloadDecoding();
    EXPECT_EQ(flags_to_avoid, flags_to_avoid & known_flags);
  }

  void PreparePayloadDecoder() override {
    payload_decoder_ = std::make_unique<Decoder>();
  }

  Http2FrameDecoderListener* PrepareListener() override {
    listener_.Reset();
    return &listener_;
  }

  // Returns random flags, but only those valid for the frame type, yet not
  // those that the DecoderPeer says will affect the decoding of the payload
  // (e.g. the PRIORTY flag on a HEADERS frame or PADDED on DATA frames).
  uint8_t RandFlags() {
    return Random().Rand8() &
           KnownFlagsMaskForFrameType(DecoderPeer::FrameType()) &
           ~DecoderPeer::FlagsAffectingPayloadDecoding();
  }

  // Start decoding the payload.
  DecodeStatus StartDecodingPayload(DecodeBuffer* db) override {
    QUICHE_DVLOG(2) << "StartDecodingPayload, db->Remaining="
                    << db->Remaining();
    return payload_decoder_->StartDecodingPayload(mutable_state(), db);
  }

  // Resume decoding the payload.
  DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) override {
    QUICHE_DVLOG(2) << "ResumeDecodingPayload, db->Remaining="
                    << db->Remaining();
    return payload_decoder_->ResumeDecodingPayload(mutable_state(), db);
  }

  // Decode one frame's payload and confirm that the listener recorded the
  // expected FrameParts instance, and only FrameParts instance. The payload
  // will be decoded several times with different partitionings of the payload,
  // and after each the validator will be called.
  AssertionResult DecodePayloadAndValidateSeveralWays(
      absl::string_view payload, const FrameParts& expected) {
    auto validator = [&expected, this]() -> AssertionResult {
      HTTP2_VERIFY_FALSE(listener_.IsInProgress());
      HTTP2_VERIFY_EQ(1u, listener_.size());
      return expected.VerifyEquals(*listener_.frame(0));
    };
    return PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(
        payload, ValidateDoneAndEmpty(validator));
  }

  // Decode one frame's payload, expecting that the final status will be
  // kDecodeError, and that OnFrameSizeError will have been called on the
  // listener. The payload will be decoded several times with different
  // partitionings of the payload. The type WrappedValidator is either
  // RandomDecoderTest::Validator, RandomDecoderTest::NoArgValidator or
  // std::nullptr_t (not extra validation).
  template <typename WrappedValidator>
  ::testing::AssertionResult VerifyDetectsFrameSizeError(
      absl::string_view payload, const Http2FrameHeader& header,
      WrappedValidator wrapped_validator) {
    set_frame_header(header);
    // If wrapped_validator is not a RandomDecoderTest::Validator, make it so.
    Validator validator = ToValidator(wrapped_validator);
    // And wrap that validator in another which will check that we've reached
    // the expected state of kDecodeError with OnFrameSizeError having been
    // called by the payload decoder.
    validator = [header, validator, this](
                    const DecodeBuffer& input,
                    DecodeStatus status) -> ::testing::AssertionResult {
      QUICHE_DVLOG(2) << "VerifyDetectsFrameSizeError validator; status="
                      << status << "; input.Remaining=" << input.Remaining();
      HTTP2_VERIFY_EQ(DecodeStatus::kDecodeError, status);
      HTTP2_VERIFY_FALSE(listener_.IsInProgress());
      HTTP2_VERIFY_EQ(1u, listener_.size());
      const FrameParts* frame = listener_.frame(0);
      HTTP2_VERIFY_EQ(header, frame->GetFrameHeader());
      HTTP2_VERIFY_TRUE(frame->GetHasFrameSizeError());
      // Verify did not get OnPaddingTooLong, as we should only ever produce
      // one of these two errors for a single frame.
      HTTP2_VERIFY_FALSE(frame->GetOptMissingLength());
      return validator(input, status);
    };
    return PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(
        payload, validator);
  }

  // Confirm that we get OnFrameSizeError when trying to decode unpadded_payload
  // at all sizes from zero to unpadded_payload.size(), except those sizes not
  // approved by approve_size.
  // If total_pad_length is greater than zero, then that amount of padding
  // is added to the payload (including the Pad Length field).
  // The flags will be required_flags, PADDED if total_pad_length > 0, and some
  // randomly selected flag bits not excluded by FlagsAffectingPayloadDecoding.
  ::testing::AssertionResult VerifyDetectsMultipleFrameSizeErrors(
      uint8_t required_flags, absl::string_view unpadded_payload,
      ApproveSize approve_size, int total_pad_length) {
    // required_flags should come from those that are defined for the frame
    // type AND are those that affect the decoding of the payload (otherwise,
    // the flag shouldn't be required).
    Http2FrameType frame_type = DecoderPeer::FrameType();
    HTTP2_VERIFY_EQ(required_flags,
                    required_flags & KnownFlagsMaskForFrameType(frame_type));
    HTTP2_VERIFY_EQ(
        required_flags,
        required_flags & DecoderPeer::FlagsAffectingPayloadDecoding());

    if (0 !=
        (Http2FrameFlag::PADDED & KnownFlagsMaskForFrameType(frame_type))) {
      // Frame type supports padding.
      if (total_pad_length == 0) {
        required_flags &= ~Http2FrameFlag::PADDED;
      } else {
        required_flags |= Http2FrameFlag::PADDED;
      }
    } else {
      HTTP2_VERIFY_EQ(0, total_pad_length);
    }

    bool validated = false;
    for (size_t real_payload_size = 0;
         real_payload_size <= unpadded_payload.size(); ++real_payload_size) {
      if (approve_size != nullptr && !approve_size(real_payload_size)) {
        continue;
      }
      QUICHE_VLOG(1) << "real_payload_size=" << real_payload_size;
      uint8_t flags = required_flags | RandFlags();
      Http2FrameBuilder fb;
      if (total_pad_length > 0) {
        // total_pad_length_ includes the size of the Pad Length field, and thus
        // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
        fb.AppendUInt8(total_pad_length - 1);
      }
      // Append a subset of the unpadded_payload, which the decoder should
      // determine is not a valid amount.
      fb.Append(unpadded_payload.substr(0, real_payload_size));
      if (total_pad_length > 0) {
        fb.AppendZeroes(total_pad_length - 1);
      }
      // We choose a random stream id because the payload decoders aren't
      // checking stream ids.
      uint32_t stream_id = RandStreamId();
      Http2FrameHeader header(fb.size(), frame_type, flags, stream_id);
      HTTP2_VERIFY_SUCCESS(
          VerifyDetectsFrameSizeError(fb.buffer(), header, nullptr));
      validated = true;
    }
    HTTP2_VERIFY_TRUE(validated);
    return ::testing::AssertionSuccess();
  }

  // As above, but for frames without padding.
  ::testing::AssertionResult VerifyDetectsFrameSizeError(
      uint8_t required_flags, absl::string_view unpadded_payload,
      ApproveSize approve_size) {
    Http2FrameType frame_type = DecoderPeer::FrameType();
    uint8_t known_flags = KnownFlagsMaskForFrameType(frame_type);
    HTTP2_VERIFY_EQ(0, known_flags & Http2FrameFlag::PADDED);
    HTTP2_VERIFY_EQ(0, required_flags & Http2FrameFlag::PADDED);
    return VerifyDetectsMultipleFrameSizeErrors(
        required_flags, unpadded_payload, std::move(approve_size), 0);
  }

  Listener listener_;
  std::unique_ptr<Decoder> payload_decoder_;
};

// A base class for tests parameterized by the total number of bytes of
// padding, including the Pad Length field (i.e. a total_pad_length of 0
// means unpadded as there is then no room for the Pad Length field).
// The frame type must support padding.
template <class Decoder, class DecoderPeer, class Listener>
class QUICHE_NO_EXPORT AbstractPaddablePayloadDecoderTest
    : public AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener>,
      public ::testing::WithParamInterface<int> {
  typedef AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener> Base;

 protected:
  using Base::listener_;
  using Base::Random;
  using Base::RandStreamId;
  using Base::set_frame_header;
  typedef typename Base::Validator Validator;

  AbstractPaddablePayloadDecoderTest() : total_pad_length_(GetParam()) {
    QUICHE_LOG(INFO) << "total_pad_length_ = " << total_pad_length_;
  }

  // Note that total_pad_length_ includes the size of the Pad Length field,
  // and thus ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
  bool IsPadded() const { return total_pad_length_ > 0; }

  // Value of the Pad Length field. Only call if IsPadded.
  size_t pad_length() const {
    EXPECT_TRUE(IsPadded());
    return total_pad_length_ - 1;
  }

  // Clear the frame builder and add the Pad Length field if appropriate.
  void Reset() {
    frame_builder_ = Http2FrameBuilder();
    if (IsPadded()) {
      frame_builder_.AppendUInt8(pad_length());
    }
  }

  void MaybeAppendTrailingPadding() {
    if (IsPadded()) {
      frame_builder_.AppendZeroes(pad_length());
    }
  }

  uint8_t RandFlags() {
    uint8_t flags = Base::RandFlags();
    if (IsPadded()) {
      flags |= Http2FrameFlag::PADDED;
    } else {
      flags &= ~Http2FrameFlag::PADDED;
    }
    return flags;
  }

  // Verify that we get OnPaddingTooLong when decoding payload, and that the
  // amount of missing padding is as specified. header.IsPadded must be true,
  // and the payload must be empty or the PadLength field must be too large.
  ::testing::AssertionResult VerifyDetectsPaddingTooLong(
      absl::string_view payload, const Http2FrameHeader& header,
      size_t expected_missing_length) {
    set_frame_header(header);
    auto& listener = listener_;
    Validator validator =
        [header, expected_missing_length, &listener](
            const DecodeBuffer&,
            DecodeStatus status) -> ::testing::AssertionResult {
      HTTP2_VERIFY_EQ(DecodeStatus::kDecodeError, status);
      HTTP2_VERIFY_FALSE(listener.IsInProgress());
      HTTP2_VERIFY_EQ(1u, listener.size());
      const FrameParts* frame = listener.frame(0);
      HTTP2_VERIFY_EQ(header, frame->GetFrameHeader());
      HTTP2_VERIFY_TRUE(frame->GetOptMissingLength());
      HTTP2_VERIFY_EQ(expected_missing_length,
                      frame->GetOptMissingLength().value());
      // Verify did not get OnFrameSizeError.
      HTTP2_VERIFY_FALSE(frame->GetHasFrameSizeError());
      return ::testing::AssertionSuccess();
    };
    return PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(
        payload, validator);
  }

  // Verifies that we get OnPaddingTooLong for a padded frame payload whose
  // (randomly selected) payload length is less than total_pad_length_.
  // Flags will be selected at random, except PADDED will be set and
  // flags_to_avoid will not be set. The stream id is selected at random.
  ::testing::AssertionResult VerifyDetectsPaddingTooLong() {
    uint8_t flags = RandFlags() | Http2FrameFlag::PADDED;

    // Create an all padding payload for total_pad_length_.
    int payload_length = 0;
    Http2FrameBuilder fb;
    if (IsPadded()) {
      fb.AppendUInt8(pad_length());
      fb.AppendZeroes(pad_length());
      QUICHE_VLOG(1) << "fb.size=" << fb.size();
      // Pick a random length for the payload that is shorter than neccesary.
      payload_length = Random().Uniform(fb.size());
    }

    QUICHE_VLOG(1) << "payload_length=" << payload_length;
    std::string payload = fb.buffer().substr(0, payload_length);

    // The missing length is the amount we cut off the end, unless
    // payload_length is zero, in which case the decoder knows only that 1
    // byte, the Pad Length field, is missing.
    size_t missing_length =
        payload_length == 0 ? 1 : fb.size() - payload_length;
    QUICHE_VLOG(1) << "missing_length=" << missing_length;

    const Http2FrameHeader header(payload_length, DecoderPeer::FrameType(),
                                  flags, RandStreamId());
    return VerifyDetectsPaddingTooLong(payload, header, missing_length);
  }

  // total_pad_length_ includes the size of the Pad Length field, and thus
  // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255).
  const size_t total_pad_length_;
  Http2FrameBuilder frame_builder_;
};

}  // namespace test
}  // namespace http2

#endif  // QUICHE_HTTP2_TEST_TOOLS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_
