// Copyright (c) 2016 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#ifndef TEST_UTILS_PARSER_TEST_H_
#define TEST_UTILS_PARSER_TEST_H_

#include <cstdint>
#include <new>
#include <vector>

#include "gtest/gtest.h"

#include "test_utils/limited_reader.h"
#include "test_utils/mock_callback.h"
#include "webm/buffer_reader.h"
#include "webm/reader.h"
#include "webm/status.h"

namespace webm {

// Base class for unit tests that test an instance of the Parser inteface. The
// template parameter T is the parser class being tested.
template <typename T>
class ParserTest : public testing::Test {
 public:
  // Sets the reader's internal buffer to the given buffer.
  virtual void SetReaderData(std::vector<std::uint8_t> data) {
    reader_ = BufferReader(std::move(data));
  }

  // Destroys and recreates the parser, forwarding the arguments to the
  // constructor. This is primarily useful for tests that require the parser to
  // have different constructor parameters.
  template <typename... Args>
  void ResetParser(Args&&... args) {
    parser_.~T();
    new (&parser_) T(std::forward<Args>(args)...);
  }

  // Calls Feed() on the parser, making sure it completes successfully and reads
  // size number of bytes.
  virtual void ParseAndVerify(std::uint64_t size) {
    std::uint64_t num_bytes_read = 0;
    const Status status = parser_.Feed(&callback_, &reader_, &num_bytes_read);
    ASSERT_EQ(Status::kOkCompleted, status.code);
    ASSERT_EQ(size, num_bytes_read);
  }

  // Calls Feed() on the parser, making sure it completes successfully and reads
  // all the data available in the reader.
  virtual void ParseAndVerify() { ParseAndVerify(reader_.size()); }

  // Similar to ParseAndVerify(), but instead artificially limits the reader to
  // providing one byte per call to Feed(). If Feed() returns
  // Status::kWouldBlock or Status::kOkPartial, Feed() will be called again
  // (feeding it another byte).
  virtual void IncrementalParseAndVerify() {
    const std::uint64_t expected_num_bytes_read = reader_.size();

    webm::LimitedReader limited_reader(
        std::unique_ptr<webm::Reader>(new BufferReader(std::move(reader_))));

    Status status;
    std::uint64_t num_bytes_read = 0;
    do {
      limited_reader.set_total_read_skip_limit(1);
      std::uint64_t local_num_bytes_read = 0;
      status = parser_.Feed(&callback_, &limited_reader, &local_num_bytes_read);
      num_bytes_read += local_num_bytes_read;
      const std::uint64_t kMinBytesRead = 1;
      ASSERT_GE(kMinBytesRead, local_num_bytes_read);
    } while (status.code == Status::kWouldBlock ||
             status.code == Status::kOkPartial);

    ASSERT_EQ(Status::kOkCompleted, status.code);
    ASSERT_EQ(expected_num_bytes_read, num_bytes_read);
  }

  // Calls Feed() on the parser, making sure it returns the expected status
  // code.
  virtual void ParseAndExpectResult(Status::Code expected) {
    std::uint64_t num_bytes_read = 0;
    const Status status = parser_.Feed(&callback_, &reader_, &num_bytes_read);
    ASSERT_EQ(expected, status.code);
  }

 protected:
  // These members are protected (not private) so unit tests have access to
  // them. This is intentional.

  // The parser that the unit tests will be testing.
  T parser_;

  // The callback that is used during parsing.
  MockCallback callback_;

  // The reader used for feeding data into the parser.
  BufferReader reader_;
};

}  // namespace webm

#endif  // TEST_UTILS_PARSER_TEST_H_
