// Copyright 2018 The Chromium OS 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_perception/video_frame_handler_impl.h"

#include <utility>

#include <base/check.h>
#include <base/logging.h>
#include <mojo/public/cpp/system/handle.h>
#include <mojo/public/cpp/system/platform_handle.h>

#include "media_perception/mojom/scoped_access_permission.mojom.h"
#include "media_perception/mojom/video_capture_types.mojom.h"

namespace mri {

bool VideoFrameHandlerImpl::HasValidCaptureFormat() {
  return capture_format_.width_in_pixels() > 0 &&
         capture_format_.height_in_pixels() > 0;
}

void VideoFrameHandlerImpl::SetCaptureFormat(const VideoStreamParams& params) {
  capture_format_ = params;
}

bool VideoFrameHandlerImpl::CaptureFormatsMatch(
    const VideoStreamParams& params) {
  return capture_format_.width_in_pixels() == params.width_in_pixels() &&
         capture_format_.height_in_pixels() == params.height_in_pixels() &&
         capture_format_.frame_rate_in_frames_per_second() ==
             params.frame_rate_in_frames_per_second();
}

VideoStreamParams VideoFrameHandlerImpl::GetCaptureFormat() {
  return capture_format_;
}

int VideoFrameHandlerImpl::GetFrameHandlerCount() {
  return frame_handler_map_.size();
}

int VideoFrameHandlerImpl::AddFrameHandler(
    VideoCaptureServiceClient::FrameHandler frame_handler) {
  frame_handler_id_counter_++;
  frame_handler_map_.insert(
      std::make_pair(frame_handler_id_counter_, std::move(frame_handler)));
  return frame_handler_id_counter_;
}

bool VideoFrameHandlerImpl::RemoveFrameHandler(int frame_handler_id) {
  std::map<int, VideoCaptureServiceClient::FrameHandler>::iterator it =
      frame_handler_map_.find(frame_handler_id);
  if (it == frame_handler_map_.end()) {
    return false;
  }
  frame_handler_map_.erase(frame_handler_id);
  return true;
}

mojo::PendingRemote<video_capture::mojom::VideoFrameHandler>
VideoFrameHandlerImpl::CreateInterfacePendingRemote() {
  mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> handler;
  receiver_.Bind(handler.InitWithNewPipeAndPassReceiver());
  return handler;
}

void VideoFrameHandlerImpl::OnNewBuffer(
    int32_t buffer_id, media::mojom::VideoBufferHandlePtr buffer_handle) {
  LOG(INFO) << "On new buffer";
  CHECK(buffer_handle->is_shared_memory_via_raw_file_descriptor());
  base::ScopedPlatformFile platform_file;
  MojoResult mojo_result = mojo::UnwrapPlatformFile(
      std::move(buffer_handle->get_shared_memory_via_raw_file_descriptor()
                    ->file_descriptor_handle),
      &platform_file);
  if (mojo_result != MOJO_RESULT_OK) {
    LOG(ERROR) << "Failed to unwrap handle: " << mojo_result;
    return;
  }
  base::UnsafeSharedMemoryRegion shm_region =
      base::UnsafeSharedMemoryRegion::Deserialize(
          base::subtle::PlatformSharedMemoryRegion::Take(
              base::ScopedFD(std::move(platform_file)),
              base::subtle::PlatformSharedMemoryRegion::Mode::kUnsafe,
              buffer_handle->get_shared_memory_via_raw_file_descriptor()
                  ->shared_memory_size_in_bytes,
              base::UnguessableToken::Create()));
  if (!shm_region.IsValid()) {
    LOG(ERROR) << "Failed to unwrap handle to valid shared memory region.";
    return;
  }
  base::WritableSharedMemoryMapping shm_mapping = shm_region.Map();
  if (!shm_mapping.IsValid()) {
    LOG(ERROR) << "Failed to map shared memory region.";
    return;
  }
  incoming_buffer_id_to_buffer_map_.insert(
      std::make_pair(buffer_id, std::move(shm_mapping)));
}

void VideoFrameHandlerImpl::OnFrameAccessHandlerReady(
    mojo::PendingRemote<video_capture::mojom::VideoFrameAccessHandler>
        frame_access_handler) {
  LOG(INFO) << "Got call to OnFrameAccessHandlerReady";
  frame_access_handler_.Bind(std::move(frame_access_handler));
}

void VideoFrameHandlerImpl::OnFrameReadyInBuffer(
    video_capture::mojom::ReadyFrameInBufferPtr buffer,
    std::vector<video_capture::mojom::ReadyFrameInBufferPtr> scaled_buffers) {
  base::WritableSharedMemoryMapping* incoming_buffer =
      &incoming_buffer_id_to_buffer_map_.at(buffer->buffer_id);
  // Loop through all the registered frame handlers and push a frame out.
  for (auto& entry : frame_handler_map_) {
    entry.second(buffer->frame_info->timestamp->microseconds,
                 incoming_buffer->GetMemoryAs<const uint8_t>(),
                 incoming_buffer->size(), capture_format_.width_in_pixels(),
                 capture_format_.height_in_pixels());
  }
  frame_access_handler_->OnFinishedConsumingBuffer(buffer->buffer_id);
}

void VideoFrameHandlerImpl::OnFrameDropped(
    ::media::mojom::VideoCaptureFrameDropReason reason) {
  LOG(WARNING) << "Got call to OnFrameDropped: " << reason;
}

void VideoFrameHandlerImpl::OnBufferRetired(int32_t buffer_id) {
  incoming_buffer_id_to_buffer_map_.erase(buffer_id);
}

// The following methods are not needed to be implementated, as far as we know
// now.
void VideoFrameHandlerImpl::OnError(::media::mojom::VideoCaptureError error) {
  LOG(ERROR) << "Got call to OnError: " << error;
}

void VideoFrameHandlerImpl::OnLog(const std::string& message) {
  LOG(INFO) << "Got call to OnLog: " << message;
}

void VideoFrameHandlerImpl::OnStarted() {
  LOG(INFO) << "Got call to OnStarted";
}

void VideoFrameHandlerImpl::OnStartedUsingGpuDecode() {
  LOG(INFO) << "Got call on OnStartedUsingGpuDecode";
}

void VideoFrameHandlerImpl::OnStopped() {
  LOG(INFO) << "Got call to OnStopped";
}

}  // namespace mri
