/*
 *  Copyright (c) 2017 The WebRTC 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.
 */

#include "modules/video_coding/frame_buffer2.h"
#include "modules/video_coding/timing/timing.h"
#include "test/scoped_key_value_config.h"
#include "test/time_controller/simulated_time_controller.h"

namespace webrtc {

namespace {

// When DataReader runs out of data provided in the constructor it will
// just set/return 0 instead.
struct DataReader {
  DataReader(const uint8_t* data, size_t size) : data_(data), size_(size) {}

  void CopyTo(void* destination, size_t dest_size) {
    memset(destination, 0, dest_size);

    size_t bytes_to_copy = std::min(size_ - offset_, dest_size);
    memcpy(destination, data_ + offset_, bytes_to_copy);
    offset_ += bytes_to_copy;
  }

  template <typename T>
  T GetNum() {
    T res;
    if (offset_ + sizeof(res) < size_) {
      memcpy(&res, data_ + offset_, sizeof(res));
      offset_ += sizeof(res);
      return res;
    }

    offset_ = size_;
    return T(0);
  }

  bool MoreToRead() { return offset_ < size_; }

  const uint8_t* const data_;
  size_t size_;
  size_t offset_ = 0;
};

class FuzzyFrameObject : public EncodedFrame {
 public:
  FuzzyFrameObject() {}
  ~FuzzyFrameObject() {}

  int64_t ReceivedTime() const override { return 0; }
  int64_t RenderTime() const override { return _renderTimeMs; }
};
}  // namespace

void FuzzOneInput(const uint8_t* data, size_t size) {
  if (size > 10000) {
    return;
  }
  DataReader reader(data, size);
  GlobalSimulatedTimeController time_controller(Timestamp::Seconds(0));
  rtc::TaskQueue task_queue(
      time_controller.GetTaskQueueFactory()->CreateTaskQueue(
          "time_tq", TaskQueueFactory::Priority::NORMAL));
  test::ScopedKeyValueConfig field_trials;
  VCMTiming timing(time_controller.GetClock(), field_trials);
  video_coding::FrameBuffer frame_buffer(time_controller.GetClock(), &timing,
                                         nullptr, field_trials);

  bool next_frame_task_running = false;

  while (reader.MoreToRead()) {
    if (reader.GetNum<uint8_t>() % 2) {
      std::unique_ptr<FuzzyFrameObject> frame(new FuzzyFrameObject());
      frame->SetId(reader.GetNum<int64_t>());
      frame->SetSpatialIndex(reader.GetNum<uint8_t>() % 5);
      frame->SetTimestamp(reader.GetNum<uint32_t>());
      frame->num_references =
          reader.GetNum<uint8_t>() % EncodedFrame::kMaxFrameReferences;

      for (size_t r = 0; r < frame->num_references; ++r)
        frame->references[r] = reader.GetNum<int64_t>();

      frame_buffer.InsertFrame(std::move(frame));
    } else {
      if (!next_frame_task_running) {
        next_frame_task_running = true;
        bool keyframe_required = reader.GetNum<uint8_t>() % 2;
        int max_wait_time_ms = reader.GetNum<uint8_t>();
        task_queue.PostTask([&task_queue, &frame_buffer,
                             &next_frame_task_running, keyframe_required,
                             max_wait_time_ms] {
          frame_buffer.NextFrame(
              max_wait_time_ms, keyframe_required, &task_queue,
              [&next_frame_task_running](std::unique_ptr<EncodedFrame> frame) {
                next_frame_task_running = false;
              });
        });
      }
    }

    time_controller.AdvanceTime(TimeDelta::Millis(reader.GetNum<uint8_t>()));
  }
}

}  // namespace webrtc
