// 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 <fuzzer/FuzzedDataProvider.h>

#include <cstddef>
#include <cstdint>
#include <limits>
#include <utility>

#include "absl/strings/string_view.h"
#include "quic/core/qpack/qpack_decoder.h"
#include "quic/core/quic_error_codes.h"
#include "quic/test_tools/qpack/qpack_decoder_test_utils.h"
#include "quic/test_tools/qpack/qpack_test_utils.h"

namespace quic {
namespace test {

struct DecoderAndHandler {
  std::unique_ptr<QpackProgressiveDecoder> decoder;
  std::unique_ptr<QpackProgressiveDecoder::HeadersHandlerInterface> handler;
};

using DecoderAndHandlerMap = std::map<QuicStreamId, DecoderAndHandler>;

// Class that sets externally owned |error_detected| to true
// on encoder stream error.
class ErrorDelegate : public QpackDecoder::EncoderStreamErrorDelegate {
 public:
  ErrorDelegate(bool* error_detected) : error_detected_(error_detected) {}
  ~ErrorDelegate() override = default;

  void OnEncoderStreamError(QuicErrorCode /*error_code*/,
                            absl::string_view /*error_message*/) override {
    *error_detected_ = true;
  }

 private:
  bool* const error_detected_;
};

// Class that destroys DecoderAndHandler when decoding completes, and sets
// externally owned |error_detected| to true on encoder stream error.
class HeadersHandler : public QpackProgressiveDecoder::HeadersHandlerInterface {
 public:
  HeadersHandler(QuicStreamId stream_id,
                 DecoderAndHandlerMap* processing_decoders,
                 bool* error_detected)
      : stream_id_(stream_id),
        processing_decoders_(processing_decoders),
        error_detected_(error_detected) {}
  ~HeadersHandler() override = default;

  void OnHeaderDecoded(absl::string_view /*name*/,
                       absl::string_view /*value*/) override {}

  // Remove DecoderAndHandler from |*processing_decoders|.
  void OnDecodingCompleted() override {
    // Will delete |this|.
    size_t result = processing_decoders_->erase(stream_id_);
    QUICHE_CHECK_EQ(1u, result);
  }

  void OnDecodingErrorDetected(QuicErrorCode /*error_code*/,
                               absl::string_view /*error_message*/) override {
    *error_detected_ = true;
  }

 private:
  const QuicStreamId stream_id_;
  DecoderAndHandlerMap* const processing_decoders_;
  bool* const error_detected_;
};

// This fuzzer exercises QpackDecoder.  It should be able to cover all possible
// code paths.  There is no point in encoding QpackDecoder's output to turn this
// into a roundtrip test, because the same header list can be encoded in many
// different ways, so the output could not be expected to match the original
// input.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  FuzzedDataProvider provider(data, size);

  // Maximum 256 byte dynamic table.  Such a small size helps test draining
  // entries and eviction.
  const uint64_t maximum_dynamic_table_capacity =
      provider.ConsumeIntegral<uint8_t>();
  // Maximum 256 blocked streams.
  const uint64_t maximum_blocked_streams = provider.ConsumeIntegral<uint8_t>();

  // |error_detected| will be set to true if an error is encountered either in a
  // header block or on the encoder stream.
  bool error_detected = false;

  ErrorDelegate encoder_stream_error_delegate(&error_detected);
  QpackDecoder decoder(maximum_dynamic_table_capacity, maximum_blocked_streams,
                       &encoder_stream_error_delegate);

  NoopQpackStreamSenderDelegate decoder_stream_sender_delegate;
  decoder.set_qpack_stream_sender_delegate(&decoder_stream_sender_delegate);

  // Decoders still reading the header block, with corresponding handlers.
  DecoderAndHandlerMap reading_decoders;

  // Decoders still processing the completely read header block,
  // with corresponding handlers.
  DecoderAndHandlerMap processing_decoders;

  // Maximum 256 data fragments to limit runtime and memory usage.
  auto fragment_count = provider.ConsumeIntegral<uint8_t>();
  while (fragment_count > 0 && !error_detected &&
         provider.remaining_bytes() > 0) {
    --fragment_count;
    switch (provider.ConsumeIntegralInRange<uint8_t>(0, 3)) {
      // Feed encoder stream data to QpackDecoder.
      case 0: {
        size_t fragment_size = provider.ConsumeIntegral<uint8_t>();
        std::string data = provider.ConsumeRandomLengthString(fragment_size);
        decoder.encoder_stream_receiver()->Decode(data);

        continue;
      }

      // Create new progressive decoder.
      case 1: {
        QuicStreamId stream_id = provider.ConsumeIntegral<uint8_t>();
        if (reading_decoders.find(stream_id) != reading_decoders.end() ||
            processing_decoders.find(stream_id) != processing_decoders.end()) {
          continue;
        }

        DecoderAndHandler decoder_and_handler;
        decoder_and_handler.handler = std::make_unique<HeadersHandler>(
            stream_id, &processing_decoders, &error_detected);
        decoder_and_handler.decoder = decoder.CreateProgressiveDecoder(
            stream_id, decoder_and_handler.handler.get());
        reading_decoders.insert({stream_id, std::move(decoder_and_handler)});

        continue;
      }

      // Feed header block data to existing decoder.
      case 2: {
        if (reading_decoders.empty()) {
          continue;
        }

        auto it = reading_decoders.begin();
        auto distance = provider.ConsumeIntegralInRange<uint8_t>(
            0, reading_decoders.size() - 1);
        std::advance(it, distance);

        size_t fragment_size = provider.ConsumeIntegral<uint8_t>();
        std::string data = provider.ConsumeRandomLengthString(fragment_size);
        it->second.decoder->Decode(data);

        continue;
      }

      // End header block.
      case 3: {
        if (reading_decoders.empty()) {
          continue;
        }

        auto it = reading_decoders.begin();
        auto distance = provider.ConsumeIntegralInRange<uint8_t>(
            0, reading_decoders.size() - 1);
        std::advance(it, distance);

        QpackProgressiveDecoder* decoder = it->second.decoder.get();

        // Move DecoderAndHandler to |reading_decoders| first, because
        // EndHeaderBlock() might synchronously call OnDecodingCompleted().
        QuicStreamId stream_id = it->first;
        processing_decoders.insert({stream_id, std::move(it->second)});
        reading_decoders.erase(it);

        decoder->EndHeaderBlock();

        continue;
      }
    }
  }

  return 0;
}

}  // namespace test
}  // namespace quic
