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

#include "media/fuchsia/camera/fake_fuchsia_camera.h"

#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>

#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/process_context.h"
#include "base/memory/platform_shared_memory_region.h"
#include "base/memory/writable_shared_memory_region.h"
#include "base/process/process_handle.h"
#include "base/task/current_thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

namespace {

constexpr uint8_t kYPlaneSalt = 1;
constexpr uint8_t kUPlaneSalt = 2;
constexpr uint8_t kVPlaneSalt = 3;

uint8_t GetTestFrameValue(gfx::Size size, int x, int y, uint8_t salt) {
  return static_cast<uint8_t>(y + x * size.height() + salt);
}

// Fills one plane of a test frame. |data| points at the location of the pixel
// (0, 0). |orientation| specifies frame orientation transformation that will be
// applied on the receiving end, so this function applies _reverse_ of the
// |orientation| transformation.
void FillPlane(uint8_t* data,
               gfx::Size size,
               int x_step,
               int y_step,
               fuchsia::camera3::Orientation orientation,
               uint8_t salt) {
  // First flip X axis for flipped orientation.
  if (orientation == fuchsia::camera3::Orientation::UP_FLIPPED ||
      orientation == fuchsia::camera3::Orientation::DOWN_FLIPPED ||
      orientation == fuchsia::camera3::Orientation::RIGHT_FLIPPED ||
      orientation == fuchsia::camera3::Orientation::LEFT_FLIPPED) {
    // Move the origin to the top right corner and flip the X axis.
    data += (size.width() - 1) * x_step;
    x_step = -x_step;
  }

  switch (orientation) {
    case fuchsia::camera3::Orientation::UP:
    case fuchsia::camera3::Orientation::UP_FLIPPED:
      break;

    case fuchsia::camera3::Orientation::DOWN:
    case fuchsia::camera3::Orientation::DOWN_FLIPPED:
      // Move |data| to point to the bottom right corner and reverse direction
      // of both axes.
      data += (size.width() - 1) * x_step + (size.height() - 1) * y_step;
      x_step = -x_step;
      y_step = -y_step;
      break;

    case fuchsia::camera3::Orientation::LEFT:
    case fuchsia::camera3::Orientation::LEFT_FLIPPED:
      // Rotate 90 degrees clockwise by moving |data| to point to the right top
      // corner, swapping the axes and reversing direction of the Y axis.
      data += (size.width() - 1) * x_step;
      size = gfx::Size(size.height(), size.width());
      std::swap(x_step, y_step);
      y_step = -y_step;
      break;

    case fuchsia::camera3::Orientation::RIGHT:
    case fuchsia::camera3::Orientation::RIGHT_FLIPPED:
      // Rotate 90 degrees counter-clockwise by moving |data| to point to the
      // bottom left corner, swapping the axes and reversing direction of the X
      // axis.
      data += (size.height() - 1) * y_step;
      size = gfx::Size(size.height(), size.width());
      std::swap(x_step, y_step);
      x_step = -x_step;
      break;
  }

  for (int y = 0; y < size.height(); ++y) {
    for (int x = 0; x < size.width(); ++x) {
      data[x * x_step + y * y_step] = GetTestFrameValue(size, x, y, salt);
    }
  }
}

void ValidatePlane(const uint8_t* data,
                   gfx::Size size,
                   size_t x_step,
                   size_t y_step,
                   uint8_t salt) {
  for (int y = 0; y < size.height(); ++y) {
    for (int x = 0; x < size.width(); ++x) {
      SCOPED_TRACE(testing::Message() << "x=" << x << " y=" << y);
      EXPECT_EQ(data[x * x_step + y * y_step],
                GetTestFrameValue(size, x, y, salt));
    }
  }
}

}  // namespace

// static
const gfx::Size FakeCameraStream::kMaxFrameSize = gfx::Size(100, 60);
// static
const gfx::Size FakeCameraStream::kDefaultFrameSize = gfx::Size(60, 40);

// static
void FakeCameraStream::ValidateFrameData(const uint8_t* data,
                                         gfx::Size size,
                                         uint8_t salt) {
  const uint8_t* y_plane = data;
  {
    SCOPED_TRACE("Y plane");
    ValidatePlane(y_plane, size, 1, size.width(), salt + kYPlaneSalt);
  }

  gfx::Size uv_size(size.width() / 2, size.height() / 2);
  const uint8_t* u_plane = y_plane + size.width() * size.height();
  {
    SCOPED_TRACE("U plane");
    ValidatePlane(u_plane, uv_size, 1, uv_size.width(), salt + kUPlaneSalt);
  }

  const uint8_t* v_plane = u_plane + uv_size.width() * uv_size.height();
  {
    SCOPED_TRACE("V plane");
    ValidatePlane(v_plane, uv_size, 1, uv_size.width(), salt + kVPlaneSalt);
  }
}

struct FakeCameraStream::Buffer {
  explicit Buffer(base::WritableSharedMemoryMapping mapping)
      : mapping(std::move(mapping)),
        release_fence_watch_controller(FROM_HERE) {}

  base::WritableSharedMemoryMapping mapping;

  // Frame is used by the client when the |release_fence| is not null.
  zx::eventpair release_fence;

  base::MessagePumpForIO::ZxHandleWatchController
      release_fence_watch_controller;
};

FakeCameraStream::FakeCameraStream()
    : binding_(this),
      sysmem_allocator_(base::ComponentContextForProcess()
                            ->svc()
                            ->Connect<fuchsia::sysmem::Allocator>()) {
  sysmem_allocator_->SetDebugClientInfo("ChromiumFakeCameraStream",
                                        base::GetCurrentProcId());
}

FakeCameraStream::~FakeCameraStream() = default;

void FakeCameraStream::Bind(
    fidl::InterfaceRequest<fuchsia::camera3::Stream> request) {
  binding_.Bind(std::move(request));
}

void FakeCameraStream::SetFirstBufferCollectionFailMode(
    SysmemFailMode fail_mode) {
  first_buffer_collection_fail_mode_ = fail_mode;
}

void FakeCameraStream::SetFakeResolution(gfx::Size resolution) {
  resolution_ = resolution;
  resolution_update_ =
      fuchsia::math::Size{resolution_.width(), resolution_.height()};
  SendResolution();
}

void FakeCameraStream::SetFakeOrientation(
    fuchsia::camera3::Orientation orientation) {
  orientation_ = orientation;
  orientation_update_ = orientation;
  SendOrientation();
}

bool FakeCameraStream::WaitBuffersAllocated() {
  EXPECT_FALSE(wait_buffers_allocated_run_loop_);

  if (!buffers_.empty())
    return true;

  wait_buffers_allocated_run_loop_.emplace();
  wait_buffers_allocated_run_loop_->Run();
  wait_buffers_allocated_run_loop_.reset();

  return !buffers_.empty();
}

bool FakeCameraStream::WaitFreeBuffer() {
  EXPECT_FALSE(wait_free_buffer_run_loop_);

  if (num_used_buffers_ < buffers_.size())
    return true;

  wait_free_buffer_run_loop_.emplace();
  wait_free_buffer_run_loop_->Run();
  wait_free_buffer_run_loop_.reset();

  return num_used_buffers_ < buffers_.size();
}

void FakeCameraStream::ProduceFrame(base::TimeTicks timestamp, uint8_t salt) {
  ASSERT_LT(num_used_buffers_, buffers_.size());
  ASSERT_FALSE(next_frame_);

  size_t index = buffers_.size();
  for (size_t i = 0; i < buffers_.size(); ++i) {
    if (!buffers_[i]->release_fence) {
      index = i;
      break;
    }
  }
  EXPECT_LT(index, buffers_.size());

  auto* buffer = buffers_[index].get();

  gfx::Size coded_size((resolution_.width() + 1) & ~1,
                       (resolution_.height() + 1) & ~1);

  // Fill Y plane.
  uint8_t* y_plane = reinterpret_cast<uint8_t*>(buffer->mapping.memory());
  size_t stride = kMaxFrameSize.width();
  FillPlane(y_plane, coded_size, /*x_step=*/1, /*y_step=*/stride, orientation_,
            salt + kYPlaneSalt);

  // Fill UV plane.
  gfx::Size uv_size(coded_size.width() / 2, coded_size.height() / 2);
  uint8_t* uv_plane = y_plane + kMaxFrameSize.width() * kMaxFrameSize.height();
  FillPlane(uv_plane, uv_size, /*x_step=*/2, /*y_step=*/stride, orientation_,
            salt + kUPlaneSalt);
  FillPlane(uv_plane + 1, uv_size, /*x_step=*/2, /*y_step=*/stride,
            orientation_, salt + kVPlaneSalt);

  // Create FrameInfo.
  fuchsia::camera3::FrameInfo frame;
  frame.frame_counter = frame_counter_++;
  frame.buffer_index = 0;
  frame.timestamp = timestamp.ToZxTime();
  EXPECT_EQ(
      zx::eventpair::create(0u, &frame.release_fence, &buffer->release_fence),
      ZX_OK);

  // Watch release fence to get notified when the frame is released.
  base::CurrentIOThread::Get()->WatchZxHandle(
      buffer->release_fence.get(), /*persistent=*/false,
      ZX_EVENTPAIR_PEER_CLOSED, &buffer->release_fence_watch_controller, this);

  num_used_buffers_++;
  next_frame_ = std::move(frame);
  SendNextFrame();
}

void FakeCameraStream::WatchResolution(WatchResolutionCallback callback) {
  EXPECT_FALSE(watch_resolution_callback_);
  watch_resolution_callback_ = std::move(callback);
  SendResolution();
}

void FakeCameraStream::WatchOrientation(WatchOrientationCallback callback) {
  EXPECT_FALSE(watch_orientation_callback_);
  watch_orientation_callback_ = std::move(callback);
  SendOrientation();
}

void FakeCameraStream::SetBufferCollection(
    fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
        token_handle) {
  EXPECT_TRUE(token_handle);

  // Drop old buffers.
  buffers_.clear();
  if (buffer_collection_) {
    buffer_collection_->Close();
    buffer_collection_.Unbind();
  }

  new_buffer_collection_token_.Bind(std::move(token_handle));
  new_buffer_collection_token_.set_error_handler(
      fit::bind_member(this, &FakeCameraStream::OnBufferCollectionError));

  // Duplicate the token to access from the stream.
  fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
      token_for_client;
  new_buffer_collection_token_->Duplicate(ZX_RIGHT_SAME_RIGHTS,
                                          token_for_client.NewRequest());

  fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> failed_token;
  if (first_buffer_collection_fail_mode_ == SysmemFailMode::kFailSync) {
    // Create an additional token that's dropped in OnBufferCollectionSyncDone()
    // before buffers are allocated. This will cause sysmem to fail the
    // collection, so the future attempt to Sync() the collection from the
    // production code will fail as well.
    new_buffer_collection_token_->Duplicate(
        /*rights_attenuation_mask=*/0, failed_token.NewRequest());
  }

  new_buffer_collection_token_->Sync(
      [this, token_for_client = std::move(token_for_client),
       failed_token = std::move(failed_token)]() mutable {
        OnBufferCollectionSyncDone(std::move(token_for_client),
                                   std::move(failed_token));
      });
}

void FakeCameraStream::WatchBufferCollection(
    WatchBufferCollectionCallback callback) {
  EXPECT_FALSE(watch_buffer_collection_callback_);
  watch_buffer_collection_callback_ = std::move(callback);
  SendBufferCollection();
}

void FakeCameraStream::GetNextFrame(GetNextFrameCallback callback) {
  EXPECT_FALSE(get_next_frame_callback_);
  get_next_frame_callback_ = std::move(callback);
  SendNextFrame();
}

void FakeCameraStream::NotImplemented_(const std::string& name) {
  ADD_FAILURE() << "NotImplemented_: " << name;
}

void FakeCameraStream::OnBufferCollectionSyncDone(
    fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
        token_for_client,
    fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
        failed_token) {
  // Return the token back to the client.
  new_buffer_collection_token_for_client_ = std::move(token_for_client);
  SendBufferCollection();

  // Initialize the new collection using |local_token|.
  sysmem_allocator_->BindSharedCollection(
      std::move(new_buffer_collection_token_), buffer_collection_.NewRequest());

  buffer_collection_.set_error_handler(
      fit::bind_member(this, &FakeCameraStream::OnBufferCollectionError));

  fuchsia::sysmem::BufferCollectionConstraints constraints;
  constraints.usage.cpu =
      fuchsia::sysmem::cpuUsageRead | fuchsia::sysmem::cpuUsageWrite;

  // The client is expected to request buffers it may need. We don't need to
  // reserve any for the server side.
  constraints.min_buffer_count_for_camping = 0;

  // Initialize image format.
  constraints.image_format_constraints_count = 1;
  constraints.image_format_constraints[0].pixel_format.type =
      fuchsia::sysmem::PixelFormatType::NV12;
  constraints.image_format_constraints[0].color_spaces_count = 1;
  constraints.image_format_constraints[0].color_space[0].type =
      fuchsia::sysmem::ColorSpaceType::REC601_NTSC;
  constraints.image_format_constraints[0].required_max_coded_width =
      kMaxFrameSize.width();
  constraints.image_format_constraints[0].required_max_coded_height =
      kMaxFrameSize.height();

  if (first_buffer_collection_fail_mode_ == SysmemFailMode::kFailAllocation) {
    // Set color space to SRGB to trigger sysmem collection failure (SRGB is not
    // compatible with NV12 pixel type).
    constraints.image_format_constraints[0].color_space[0].type =
        fuchsia::sysmem::ColorSpaceType::SRGB;
  }

  buffer_collection_->SetConstraints(/*has_constraints=*/true,
                                     std::move(constraints));
  buffer_collection_->WaitForBuffersAllocated(
      fit::bind_member(this, &FakeCameraStream::OnBufferCollectionAllocated));
}

void FakeCameraStream::OnBufferCollectionError(zx_status_t status) {
  if (first_buffer_collection_fail_mode_ != SysmemFailMode::kNone) {
    first_buffer_collection_fail_mode_ = SysmemFailMode::kNone;

    // Create a new buffer collection to retry buffer allocation.
    fuchsia::sysmem::BufferCollectionTokenPtr token;
    sysmem_allocator_->AllocateSharedCollection(token.NewRequest());
    SetBufferCollection(std::move(token));
    return;
  }

  ADD_FAILURE() << "BufferCollection failed.";
  if (wait_buffers_allocated_run_loop_)
    wait_buffers_allocated_run_loop_->Quit();
  if (wait_free_buffer_run_loop_)
    wait_free_buffer_run_loop_->Quit();
}

void FakeCameraStream::OnBufferCollectionAllocated(
    zx_status_t status,
    fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info) {
  if (status != ZX_OK) {
    OnBufferCollectionError(status);
    return;
  }

  EXPECT_TRUE(buffers_.empty());
  EXPECT_TRUE(buffer_collection_info.settings.has_image_format_constraints);
  EXPECT_EQ(buffer_collection_info.settings.image_format_constraints
                .pixel_format.type,
            fuchsia::sysmem::PixelFormatType::NV12);

  size_t buffer_size =
      buffer_collection_info.settings.buffer_settings.size_bytes;
  for (size_t i = 0; i < buffer_collection_info.buffer_count; ++i) {
    auto& buffer = buffer_collection_info.buffers[i];
    EXPECT_EQ(buffer.vmo_usable_start, 0U);
    auto region = base::WritableSharedMemoryRegion::Deserialize(
        base::subtle::PlatformSharedMemoryRegion::Take(
            std::move(buffer.vmo),
            base::subtle::PlatformSharedMemoryRegion::Mode::kWritable,
            buffer_size, base::UnguessableToken::Create()));
    auto mapping = region.Map();
    EXPECT_TRUE(mapping.IsValid());
    buffers_.push_back(std::make_unique<Buffer>(std::move(mapping)));
  }

  if (wait_buffers_allocated_run_loop_)
    wait_buffers_allocated_run_loop_->Quit();
}

void FakeCameraStream::SendResolution() {
  if (!watch_resolution_callback_ || !resolution_update_)
    return;
  watch_resolution_callback_(resolution_update_.value());
  watch_resolution_callback_ = {};
  resolution_update_.reset();
}

void FakeCameraStream::SendOrientation() {
  if (!watch_orientation_callback_ || !orientation_update_)
    return;
  watch_orientation_callback_(orientation_update_.value());
  watch_orientation_callback_ = {};
  orientation_update_.reset();
}

void FakeCameraStream::SendBufferCollection() {
  if (!watch_buffer_collection_callback_ ||
      !new_buffer_collection_token_for_client_) {
    return;
  }
  watch_buffer_collection_callback_(
      std::move(new_buffer_collection_token_for_client_.value()));
  watch_buffer_collection_callback_ = {};
  new_buffer_collection_token_for_client_.reset();
}

void FakeCameraStream::SendNextFrame() {
  if (!get_next_frame_callback_ || !next_frame_)
    return;
  get_next_frame_callback_(std::move(next_frame_.value()));
  get_next_frame_callback_ = {};
  next_frame_.reset();
}

void FakeCameraStream::OnZxHandleSignalled(zx_handle_t handle,
                                           zx_signals_t signals) {
  EXPECT_EQ(signals, ZX_EVENTPAIR_PEER_CLOSED);

  // Find the buffer that corresponds to the |handle|.
  size_t index = buffers_.size();
  for (size_t i = 0; i < buffers_.size(); ++i) {
    if (buffers_[i]->release_fence.get() == handle) {
      index = i;
      break;
    }
  }
  ASSERT_LT(index, buffers_.size());
  buffers_[index]->release_fence = {};
  buffers_[index]->release_fence_watch_controller.StopWatchingZxHandle();
  num_used_buffers_--;

  if (wait_free_buffer_run_loop_)
    wait_free_buffer_run_loop_->Quit();
}
FakeCameraDevice::FakeCameraDevice() = default;
FakeCameraDevice::~FakeCameraDevice() = default;

void FakeCameraDevice::Bind(
    fidl::InterfaceRequest<fuchsia::camera3::Device> request) {
  bindings_.AddBinding(this, std::move(request));
}

void FakeCameraDevice::SetGetIdentifierHandler(
    base::RepeatingCallback<void(GetIdentifierCallback)>
        get_identifier_handler) {
  get_identifier_handler_ = std::move(get_identifier_handler);
}

void FakeCameraDevice::GetIdentifier(GetIdentifierCallback callback) {
  if (get_identifier_handler_) {
    get_identifier_handler_.Run(std::move(callback));
    return;
  }

  callback("Fake Camera");
}

void FakeCameraDevice::GetConfigurations(GetConfigurationsCallback callback) {
  std::vector<fuchsia::camera3::Configuration> configurations(1);
  configurations[0].streams.resize(1);
  configurations[0].streams[0].frame_rate.numerator = 30;
  configurations[0].streams[0].frame_rate.denominator = 1;
  configurations[0].streams[0].image_format.pixel_format.type =
      fuchsia::sysmem::PixelFormatType::NV12;
  configurations[0].streams[0].image_format.coded_width = 640;
  configurations[0].streams[0].image_format.coded_height = 480;
  configurations[0].streams[0].image_format.bytes_per_row = 640;
  callback(std::move(configurations));
}

void FakeCameraDevice::ConnectToStream(
    uint32_t index,
    fidl::InterfaceRequest<fuchsia::camera3::Stream> request) {
  EXPECT_EQ(index, 0U);
  stream_.Bind(std::move(request));
}

void FakeCameraDevice::NotImplemented_(const std::string& name) {
  ADD_FAILURE() << "NotImplemented_: " << name;
}

FakeCameraDeviceWatcher::FakeCameraDeviceWatcher(
    sys::OutgoingDirectory* outgoing_directory) {
  zx_status_t status =
      outgoing_directory->AddPublicService<fuchsia::camera3::DeviceWatcher>(
          [this](
              fidl::InterfaceRequest<fuchsia::camera3::DeviceWatcher> request) {
            auto client = std::make_unique<Client>(this);

            // Queue events for all existing devices.
            for (auto& device : devices_) {
              fuchsia::camera3::WatchDevicesEvent event;
              event.set_added(device.first);
              client->QueueEvent(std::move(event));
            }

            bindings_.AddBinding(std::move(client), std::move(request));
          });
  ZX_CHECK(status == ZX_OK, status) << "AddPublicService failed";

  devices_.insert(
      std::make_pair(next_device_id_++, std::make_unique<FakeCameraDevice>()));
}

FakeCameraDeviceWatcher::~FakeCameraDeviceWatcher() = default;

void FakeCameraDeviceWatcher::DisconnectClients() {
  bindings_.CloseAll();
}

std::unique_ptr<FakeCameraDevice> FakeCameraDeviceWatcher::RemoveDevice(
    uint64_t device_id) {
  auto device_it = devices_.find(device_id);
  DCHECK(device_it != devices_.end());

  // Queue an event for each client to inform about the device removal.
  for (auto& binding : bindings_.bindings()) {
    fuchsia::camera3::WatchDevicesEvent event;
    event.set_removed(device_id);
    binding->impl()->QueueEvent(std::move(event));
  }

  std::unique_ptr<FakeCameraDevice> device = std::move(device_it->second);
  devices_.erase(device_it);

  return device;
}

FakeCameraDeviceWatcher::Client::Client(FakeCameraDeviceWatcher* device_watcher)
    : device_watcher_(device_watcher) {}
FakeCameraDeviceWatcher::Client::~Client() {}

void FakeCameraDeviceWatcher::Client::QueueEvent(
    fuchsia::camera3::WatchDevicesEvent event) {
  event_queue_.push_back(std::move(event));

  if (watch_devices_callback_) {
    watch_devices_callback_(std::move(event_queue_));
    event_queue_.clear();
    watch_devices_callback_ = {};
  }
}

void FakeCameraDeviceWatcher::Client::WatchDevices(
    WatchDevicesCallback callback) {
  DCHECK(!watch_devices_callback_);

  if (initial_list_sent_ && event_queue_.empty()) {
    watch_devices_callback_ = std::move(callback);
    return;
  }

  callback(std::move(event_queue_));
  event_queue_.clear();
  initial_list_sent_ = true;
}

void FakeCameraDeviceWatcher::Client::ConnectToDevice(
    uint64_t id,
    fidl::InterfaceRequest<fuchsia::camera3::Device> request) {
  auto it = device_watcher_->devices().find(id);
  if (it == device_watcher_->devices().end())
    return;
  it->second->Bind(std::move(request));
}

void FakeCameraDeviceWatcher::Client::NotImplemented_(const std::string& name) {
  ADD_FAILURE() << "NotImplemented_: " << name;
}

}  // namespace media
