// 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 "quiche/http2/test_tools/random_decoder_test.h"

#include <stddef.h>

#include <algorithm>
#include <memory>

#include "quiche/http2/decoder/decode_buffer.h"
#include "quiche/http2/decoder/decode_status.h"
#include "quiche/http2/http2_constants.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/platform/api/quiche_test.h"
#include "quiche/common/platform/api/quiche_test_helpers.h"

using ::testing::AssertionResult;

namespace http2 {
namespace test {

RandomDecoderTest::RandomDecoderTest() = default;

bool RandomDecoderTest::StopDecodeOnDone() { return stop_decode_on_done_; }

DecodeStatus RandomDecoderTest::DecodeSegments(DecodeBuffer* original,
                                               const SelectSize& select_size) {
  DecodeStatus status = DecodeStatus::kDecodeInProgress;
  bool first = true;
  QUICHE_VLOG(2) << "DecodeSegments: input size=" << original->Remaining();
  while (first || original->HasData()) {
    size_t remaining = original->Remaining();
    size_t size =
        std::min(remaining, select_size(first, original->Offset(), remaining));
    DecodeBuffer db(original->cursor(), size);
    QUICHE_VLOG(2) << "Decoding " << size << " bytes of " << remaining
                   << " remaining";
    if (first) {
      first = false;
      status = StartDecoding(&db);
    } else {
      status = ResumeDecoding(&db);
    }
    // A decoder MUST consume some input (if any is available), else we could
    // get stuck in infinite loops.
    if (db.Offset() == 0 && db.HasData() &&
        status != DecodeStatus::kDecodeError) {
      ADD_FAILURE() << "Decoder didn't make any progress; db.FullSize="
                    << db.FullSize()
                    << "   original.Offset=" << original->Offset();
      return DecodeStatus::kDecodeError;
    }
    original->AdvanceCursor(db.Offset());
    switch (status) {
      case DecodeStatus::kDecodeDone:
        if (original->Empty() || StopDecodeOnDone()) {
          return DecodeStatus::kDecodeDone;
        }
        continue;
      case DecodeStatus::kDecodeInProgress:
        continue;
      case DecodeStatus::kDecodeError:
        return DecodeStatus::kDecodeError;
    }
  }
  return status;
}

// Decode |original| multiple times, with different segmentations, validating
// after each decode, returning on the first failure.
AssertionResult RandomDecoderTest::DecodeAndValidateSeveralWays(
    DecodeBuffer* original, bool return_non_zero_on_first,
    const Validator& validator) {
  const uint32_t original_remaining = original->Remaining();
  QUICHE_VLOG(1) << "DecodeAndValidateSeveralWays - Start, remaining = "
                 << original_remaining;
  uint32_t first_consumed;
  {
    // Fast decode (no stopping unless decoder does so).
    DecodeBuffer input(original->cursor(), original_remaining);
    QUICHE_VLOG(2) << "DecodeSegmentsAndValidate with SelectRemaining";
    VERIFY_SUCCESS(
        DecodeSegmentsAndValidate(&input, SelectRemaining(), validator))
        << "\nFailed with SelectRemaining; input.Offset=" << input.Offset()
        << "; input.Remaining=" << input.Remaining();
    first_consumed = input.Offset();
  }
  if (original_remaining <= 30) {
    // Decode again, one byte at a time.
    DecodeBuffer input(original->cursor(), original_remaining);
    QUICHE_VLOG(2) << "DecodeSegmentsAndValidate with SelectOne";
    VERIFY_SUCCESS(DecodeSegmentsAndValidate(&input, SelectOne(), validator))
        << "\nFailed with SelectOne; input.Offset=" << input.Offset()
        << "; input.Remaining=" << input.Remaining();
    VERIFY_EQ(first_consumed, input.Offset()) << "\nFailed with SelectOne";
  }
  if (original_remaining <= 20) {
    // Decode again, one or zero bytes at a time.
    DecodeBuffer input(original->cursor(), original_remaining);
    QUICHE_VLOG(2) << "DecodeSegmentsAndValidate with SelectZeroAndOne";
    VERIFY_SUCCESS(DecodeSegmentsAndValidate(
        &input, SelectZeroAndOne(return_non_zero_on_first), validator))
        << "\nFailed with SelectZeroAndOne";
    VERIFY_EQ(first_consumed, input.Offset())
        << "\nFailed with SelectZeroAndOne; input.Offset=" << input.Offset()
        << "; input.Remaining=" << input.Remaining();
  }
  {
    // Decode again, with randomly selected segment sizes.
    DecodeBuffer input(original->cursor(), original_remaining);
    QUICHE_VLOG(2) << "DecodeSegmentsAndValidate with SelectRandom";
    VERIFY_SUCCESS(DecodeSegmentsAndValidate(
        &input, SelectRandom(return_non_zero_on_first), validator))
        << "\nFailed with SelectRandom; input.Offset=" << input.Offset()
        << "; input.Remaining=" << input.Remaining();
    VERIFY_EQ(first_consumed, input.Offset()) << "\nFailed with SelectRandom";
  }
  VERIFY_EQ(original_remaining, original->Remaining());
  original->AdvanceCursor(first_consumed);
  QUICHE_VLOG(1) << "DecodeAndValidateSeveralWays - SUCCESS";
  return ::testing::AssertionSuccess();
}

// static
RandomDecoderTest::SelectSize RandomDecoderTest::SelectZeroAndOne(
    bool return_non_zero_on_first) {
  std::shared_ptr<bool> zero_next(new bool);
  *zero_next = !return_non_zero_on_first;
  return [zero_next](bool /*first*/, size_t /*offset*/,
                     size_t /*remaining*/) -> size_t {
    if (*zero_next) {
      *zero_next = false;
      return 0;
    } else {
      *zero_next = true;
      return 1;
    }
  };
}

RandomDecoderTest::SelectSize RandomDecoderTest::SelectRandom(
    bool return_non_zero_on_first) {
  return [this, return_non_zero_on_first](bool first, size_t /*offset*/,
                                          size_t remaining) -> size_t {
    uint32_t r = random_.Rand32();
    if (first && return_non_zero_on_first) {
      QUICHE_CHECK_LT(0u, remaining);
      if (remaining == 1) {
        return 1;
      }
      return 1 + (r % remaining);  // size in range [1, remaining).
    }
    return r % (remaining + 1);  // size in range [0, remaining].
  };
}

uint32_t RandomDecoderTest::RandStreamId() {
  return random_.Rand32() & StreamIdMask();
}

}  // namespace test
}  // namespace http2
