/*
 *  Copyright (c) 2020 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.
 */

#ifndef TEST_MAPPABLE_NATIVE_BUFFER_H_
#define TEST_MAPPABLE_NATIVE_BUFFER_H_

#include <utility>
#include <vector>

#include "api/array_view.h"
#include "api/video/video_frame.h"
#include "common_video/include/video_frame_buffer.h"
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/synchronization/mutex.h"

namespace webrtc {
namespace test {

class MappableNativeBuffer;

VideoFrame CreateMappableNativeFrame(int64_t ntp_time_ms,
                                     VideoFrameBuffer::Type mappable_type,
                                     int width,
                                     int height);

rtc::scoped_refptr<MappableNativeBuffer> GetMappableNativeBufferFromVideoFrame(
    const VideoFrame& frame);

// A for-testing native buffer that is scalable and mappable. The contents of
// the buffer is black and the pixels are created upon mapping. Mapped buffers
// are stored inside MappableNativeBuffer, allowing tests to verify which
// resolutions were mapped, e.g. when passing them in to an encoder or other
// modules.
class MappableNativeBuffer : public VideoFrameBuffer {
 public:
  // If `allow_i420_conversion` is false, calling ToI420() on a non-I420 buffer
  // will DCHECK-crash. Used to ensure zero-copy in tests.
  MappableNativeBuffer(VideoFrameBuffer::Type mappable_type,
                       int width,
                       int height);
  ~MappableNativeBuffer() override;

  VideoFrameBuffer::Type mappable_type() const { return mappable_type_; }

  VideoFrameBuffer::Type type() const override { return Type::kNative; }
  int width() const override { return width_; }
  int height() const override { return height_; }

  rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
                                                    int offset_y,
                                                    int crop_width,
                                                    int crop_height,
                                                    int scaled_width,
                                                    int scaled_height) override;

  rtc::scoped_refptr<I420BufferInterface> ToI420() override;
  rtc::scoped_refptr<VideoFrameBuffer> GetMappedFrameBuffer(
      rtc::ArrayView<VideoFrameBuffer::Type> types) override;

  // Gets all the buffers that have been mapped so far, including mappings of
  // cropped and scaled buffers.
  std::vector<rtc::scoped_refptr<VideoFrameBuffer>> GetMappedFramedBuffers()
      const;
  bool DidConvertToI420() const;

 private:
  friend class rtc::RefCountedObject<MappableNativeBuffer>;

  class ScaledBuffer : public VideoFrameBuffer {
   public:
    ScaledBuffer(rtc::scoped_refptr<MappableNativeBuffer> parent,
                 int width,
                 int height);
    ~ScaledBuffer() override;

    VideoFrameBuffer::Type type() const override { return Type::kNative; }
    int width() const override { return width_; }
    int height() const override { return height_; }

    rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(
        int offset_x,
        int offset_y,
        int crop_width,
        int crop_height,
        int scaled_width,
        int scaled_height) override;

    rtc::scoped_refptr<I420BufferInterface> ToI420() override;
    rtc::scoped_refptr<VideoFrameBuffer> GetMappedFrameBuffer(
        rtc::ArrayView<VideoFrameBuffer::Type> types) override;

   private:
    friend class rtc::RefCountedObject<ScaledBuffer>;

    const rtc::scoped_refptr<MappableNativeBuffer> parent_;
    const int width_;
    const int height_;
  };

  rtc::scoped_refptr<ScaledBuffer> FullSizeBuffer();
  rtc::scoped_refptr<VideoFrameBuffer> GetOrCreateMappedBuffer(int width,
                                                               int height);

  const VideoFrameBuffer::Type mappable_type_;
  const int width_;
  const int height_;
  mutable Mutex lock_;
  std::vector<rtc::scoped_refptr<VideoFrameBuffer>> mapped_buffers_
      RTC_GUARDED_BY(&lock_);
};

}  // namespace test
}  // namespace webrtc

#endif  //  TEST_MAPPABLE_NATIVE_BUFFER_H_
