/*
 *  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 <memory>

#include "api/task_queue/task_queue_base.h"
#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));
  std::unique_ptr<TaskQueueBase, TaskQueueDeleter> 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,
                                         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.get(),
              [&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
