// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/capture/video/chromeos/mock_video_capture_client.h"

#include <string>
#include <utility>

using testing::_;
using testing::Invoke;

namespace media {
namespace unittest_internal {

MockVideoCaptureClient::MockVideoCaptureClient() {
  ON_CALL(*this, OnError(_, _, _))
      .WillByDefault(Invoke(this, &MockVideoCaptureClient::DumpError));
}

MockVideoCaptureClient::~MockVideoCaptureClient() {
  if (quit_cb_) {
    std::move(quit_cb_).Run();
  }
}

void MockVideoCaptureClient::SetFrameCb(base::OnceClosure frame_cb) {
  frame_cb_ = std::move(frame_cb);
}

void MockVideoCaptureClient::SetQuitCb(base::OnceClosure quit_cb) {
  quit_cb_ = std::move(quit_cb);
}

void MockVideoCaptureClient::DumpError(media::VideoCaptureError,
                                       const base::Location& location,
                                       const std::string& message) {
  DPLOG(ERROR) << location.ToString() << " " << message;
}

void MockVideoCaptureClient::OnIncomingCapturedData(
    base::span<const uint8_t> data,
    const VideoCaptureFormat& format,
    const gfx::ColorSpace& color_space,
    int rotation,
    bool flip_y,
    base::TimeTicks reference_time,
    base::TimeDelta timestamp,
    std::optional<base::TimeTicks> capture_begin_time,
    const std::optional<media::VideoFrameMetadata>& metadata,
    int frame_feedback_id) {
  ASSERT_FALSE(data.empty());
  if (frame_cb_)
    std::move(frame_cb_).Run();
}

void MockVideoCaptureClient::OnIncomingCapturedImage(
    scoped_refptr<gpu::ClientSharedImage> shared_image,
    const VideoCaptureFormat& frame_format,
    int clockwise_rotation,
    base::TimeTicks reference_time,
    base::TimeDelta timestamp,
    std::optional<base::TimeTicks> capture_begin_time,
    const gfx::Size& natural_size,
    const std::optional<media::VideoFrameMetadata>& metadata,
    int frame_feedback_id) {
  ASSERT_TRUE(shared_image);
  ASSERT_FALSE(shared_image->size().IsEmpty());
  if (frame_cb_)
    std::move(frame_cb_).Run();
}

void MockVideoCaptureClient::OnIncomingCapturedExternalBuffer(
    CapturedExternalVideoBuffer buffer,
    base::TimeTicks reference_time,
    base::TimeDelta timestamp,
    std::optional<base::TimeTicks> capture_begin_time,
    const gfx::Rect& visible_rect,
    const gfx::Size& natural_size,
    const std::optional<media::VideoFrameMetadata>& metadata) {
  if (frame_cb_)
    std::move(frame_cb_).Run();
}

// Trampoline methods to workaround GMOCK problems with std::unique_ptr<>.
VideoCaptureDevice::Client::ReserveResult
MockVideoCaptureClient::ReserveOutputBuffer(
    const gfx::Size& dimensions,
    VideoPixelFormat format,
    int frame_feedback_id,
    VideoCaptureDevice::Client::Buffer* buffer,
    int* require_new_buffer_id,
    int* retire_old_buffer_id) {
  DoReserveOutputBuffer();
  NOTREACHED();
}

void MockVideoCaptureClient::OnIncomingCapturedBufferExt(
    Buffer buffer,
    const VideoCaptureFormat& format,
    const gfx::ColorSpace& color_space,
    base::TimeTicks reference_time,
    base::TimeDelta timestamp,
    std::optional<base::TimeTicks> capture_begin_time,
    gfx::Rect visible_rect,
    const std::optional<VideoFrameMetadata>& additional_metadata) {
  DoOnIncomingCapturedVideoFrame();
}

}  // namespace unittest_internal
}  // namespace media
