// Copyright 2016 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 "chrome/gpu/gpu_arc_video_service.h"

#include <utility>

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/gpu/arc_gpu_video_decode_accelerator.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/bindings/type_converter.h"
#include "mojo/public/cpp/system/platform_handle.h"

// Make sure arc::mojom::VideoAcceleratorService::Result and
// chromeos::arc::ArcVideoAccelerator::Result match.
static_assert(
    static_cast<int>(arc::mojom::VideoAcceleratorService::Result::SUCCESS) ==
        chromeos::arc::ArcVideoAccelerator::SUCCESS,
    "enum mismatch");
static_assert(static_cast<int>(
                  arc::mojom::VideoAcceleratorService::Result::ILLEGAL_STATE) ==
                  chromeos::arc::ArcVideoAccelerator::ILLEGAL_STATE,
              "enum mismatch");
static_assert(
    static_cast<int>(
        arc::mojom::VideoAcceleratorService::Result::INVALID_ARGUMENT) ==
        chromeos::arc::ArcVideoAccelerator::INVALID_ARGUMENT,
    "enum mismatch");
static_assert(
    static_cast<int>(
        arc::mojom::VideoAcceleratorService::Result::UNREADABLE_INPUT) ==
        chromeos::arc::ArcVideoAccelerator::UNREADABLE_INPUT,
    "enum mismatch");
static_assert(
    static_cast<int>(
        arc::mojom::VideoAcceleratorService::Result::PLATFORM_FAILURE) ==
        chromeos::arc::ArcVideoAccelerator::PLATFORM_FAILURE,
    "enum mismatch");
static_assert(
    static_cast<int>(
        arc::mojom::VideoAcceleratorService::Result::INSUFFICIENT_RESOURCES) ==
        chromeos::arc::ArcVideoAccelerator::INSUFFICIENT_RESOURCES,
    "enum mismatch");

namespace {
void OnConnectionError() {
  DVLOG(2) << "OnConnectionError";
}
}  // namespace

namespace mojo {

template <>
struct TypeConverter<arc::mojom::BufferMetadataPtr,
                     chromeos::arc::BufferMetadata> {
  static arc::mojom::BufferMetadataPtr Convert(
      const chromeos::arc::BufferMetadata& input) {
    arc::mojom::BufferMetadataPtr result = arc::mojom::BufferMetadata::New();
    result->timestamp = input.timestamp;
    result->bytes_used = input.bytes_used;
    return result;
  }
};

template <>
struct TypeConverter<chromeos::arc::BufferMetadata,
                     arc::mojom::BufferMetadataPtr> {
  static chromeos::arc::BufferMetadata Convert(
      const arc::mojom::BufferMetadataPtr& input) {
    chromeos::arc::BufferMetadata result;
    result.timestamp = input->timestamp;
    result.bytes_used = input->bytes_used;
    return result;
  }
};

template <>
struct TypeConverter<arc::mojom::VideoFormatPtr, chromeos::arc::VideoFormat> {
  static arc::mojom::VideoFormatPtr Convert(
      const chromeos::arc::VideoFormat& input) {
    arc::mojom::VideoFormatPtr result = arc::mojom::VideoFormat::New();
    result->pixel_format = input.pixel_format;
    result->buffer_size = input.buffer_size;
    result->min_num_buffers = input.min_num_buffers;
    result->coded_width = input.coded_width;
    result->coded_height = input.coded_height;
    result->crop_left = input.crop_left;
    result->crop_width = input.crop_width;
    result->crop_top = input.crop_top;
    result->crop_height = input.crop_height;
    return result;
  }
};

template <>
struct TypeConverter<chromeos::arc::ArcVideoAccelerator::Config,
                     arc::mojom::ArcVideoAcceleratorConfigPtr> {
  static chromeos::arc::ArcVideoAccelerator::Config Convert(
      const arc::mojom::ArcVideoAcceleratorConfigPtr& input) {
    chromeos::arc::ArcVideoAccelerator::Config result;
    result.device_type =
        static_cast<chromeos::arc::ArcVideoAccelerator::Config::DeviceType>(
            input->device_type);
    result.num_input_buffers = input->num_input_buffers;
    result.input_pixel_format = input->input_pixel_format;
    return result;
  }
};

}  // namespace mojo

namespace chromeos {
namespace arc {

GpuArcVideoService::GpuArcVideoService(
    const gpu::GpuPreferences& gpu_preferences)
    : gpu_preferences_(gpu_preferences),
      accelerator_(new ArcGpuVideoDecodeAccelerator(gpu_preferences_)) {}

GpuArcVideoService::~GpuArcVideoService() {
  DCHECK(thread_checker_.CalledOnValidThread());
}

// static
void GpuArcVideoService::DeprecatedConnect(
    std::unique_ptr<GpuArcVideoService> service,
    ::arc::mojom::VideoAcceleratorServiceClientRequest client_request) {
  DVLOG(2) << "Connect";

  service->client_.Bind(::arc::mojom::VideoAcceleratorServiceClientPtrInfo(
      client_request.PassMessagePipe(), 0u));
  service->client_.set_connection_error_handler(base::Bind(&OnConnectionError));

  ::arc::mojom::VideoAcceleratorServicePtr service_proxy;
  ::arc::mojom::VideoAcceleratorServiceRequest request =
      mojo::GetProxy(&service_proxy);
  service->client_->DeprecatedInit(std::move(service_proxy));

  auto binding = mojo::MakeStrongBinding(std::move(service),
                                         mojo::GetProxy(&service_proxy));
  binding->set_connection_error_handler(base::Bind(&OnConnectionError));
}

void GpuArcVideoService::OnError(ArcVideoAccelerator::Result error) {
  DVLOG(2) << "OnError " << error;
  DCHECK_NE(error, ArcVideoAccelerator::SUCCESS);
  DCHECK(client_);
  client_->OnError(
      static_cast<::arc::mojom::VideoAcceleratorService::Result>(error));
}

void GpuArcVideoService::OnBufferDone(PortType port,
                                      uint32_t index,
                                      const BufferMetadata& metadata) {
  DVLOG(2) << "OnBufferDone " << port << "," << index;
  DCHECK(client_);
  client_->OnBufferDone(static_cast<::arc::mojom::PortType>(port), index,
                        ::arc::mojom::BufferMetadata::From(metadata));
}

void GpuArcVideoService::OnFlushDone() {
  DVLOG(2) << "OnFlushDone";
  DCHECK(client_);
  client_->OnFlushDone();
}

void GpuArcVideoService::OnResetDone() {
  DVLOG(2) << "OnResetDone";
  DCHECK(client_);
  client_->OnResetDone();
}

void GpuArcVideoService::OnOutputFormatChanged(const VideoFormat& format) {
  DVLOG(2) << "OnOutputFormatChanged";
  DCHECK(client_);
  client_->OnOutputFormatChanged(::arc::mojom::VideoFormat::From(format));
}

void GpuArcVideoService::Initialize(
    ::arc::mojom::ArcVideoAcceleratorConfigPtr config,
    ::arc::mojom::VideoAcceleratorServiceClientPtr client,
    const InitializeCallback& callback) {
  DVLOG(2) << "Initialize";
  DCHECK(!client_);
  client_ = std::move(client);
  ArcVideoAccelerator::Result result =
      accelerator_->Initialize(config.To<ArcVideoAccelerator::Config>(), this);
  callback.Run(
      static_cast<::arc::mojom::VideoAcceleratorService::Result>(result));
}

void GpuArcVideoService::DeprecatedInitialize(
    ::arc::mojom::ArcVideoAcceleratorConfigPtr config,
    const DeprecatedInitializeCallback& callback) {
  DVLOG(2) << "DeprecatedInitialize";
  ArcVideoAccelerator::Result result =
      accelerator_->Initialize(config.To<ArcVideoAccelerator::Config>(), this);
  callback.Run(
      static_cast<::arc::mojom::VideoAcceleratorService::Result>(result));
}

base::ScopedFD GpuArcVideoService::UnwrapFdFromMojoHandle(
    mojo::ScopedHandle handle) {
  DCHECK(client_);
  if (!handle.is_valid()) {
    LOG(ERROR) << "handle is invalid";
    client_->OnError(
        ::arc::mojom::VideoAcceleratorService::Result::INVALID_ARGUMENT);
    return base::ScopedFD();
  }

  base::PlatformFile platform_file;
  MojoResult mojo_result =
      mojo::UnwrapPlatformFile(std::move(handle), &platform_file);
  if (mojo_result != MOJO_RESULT_OK) {
    LOG(ERROR) << "UnwrapPlatformFile failed: " << mojo_result;
    client_->OnError(
        ::arc::mojom::VideoAcceleratorService::Result::PLATFORM_FAILURE);
    return base::ScopedFD();
  }

  return base::ScopedFD(platform_file);
}

void GpuArcVideoService::BindSharedMemory(::arc::mojom::PortType port,
                                          uint32_t index,
                                          mojo::ScopedHandle ashmem_handle,
                                          uint32_t offset,
                                          uint32_t length) {
  DVLOG(2) << "BindSharedMemoryCallback port=" << port << ", index=" << index
           << ", offset=" << offset << ", length=" << length;

  base::ScopedFD fd = UnwrapFdFromMojoHandle(std::move(ashmem_handle));
  if (!fd.is_valid())
    return;
  accelerator_->BindSharedMemory(static_cast<PortType>(port), index,
                                 std::move(fd), offset, length);
}

void GpuArcVideoService::DeprecatedBindDmabuf(::arc::mojom::PortType port,
                                              uint32_t index,
                                              mojo::ScopedHandle dmabuf_handle,
                                              int32_t stride) {
  std::vector<::arc::mojom::ArcVideoAcceleratorDmabufPlanePtr> planes(1);
  planes[0]->offset = 0;
  planes[0]->stride = stride;

  BindDmabuf(port, index, std::move(dmabuf_handle), std::move(planes));
}

void GpuArcVideoService::BindDmabuf(
    ::arc::mojom::PortType port,
    uint32_t index,
    mojo::ScopedHandle dmabuf_handle,
    std::vector<::arc::mojom::ArcVideoAcceleratorDmabufPlanePtr>
        dmabuf_planes) {
  DVLOG(2) << "BindDmabuf port=" << port << ", index=" << index;

  base::ScopedFD fd = UnwrapFdFromMojoHandle(std::move(dmabuf_handle));
  if (!fd.is_valid())
    return;

  std::vector<ArcVideoAccelerator::DmabufPlane> converted_planes;
  // TODO(yusukes): Use mojo typemaps to simplify the code.
  for (const auto& input : dmabuf_planes) {
    if (input->offset < 0 || input->stride < 0) {
      DVLOG(1) << "Invalid offset/stride: " << input->offset << "/"
               << input->stride;
      client_->OnError(
          ::arc::mojom::VideoAcceleratorService::Result::INVALID_ARGUMENT);
      return;
    }
    converted_planes.emplace_back(input->offset, input->stride);
  }

  accelerator_->BindDmabuf(static_cast<PortType>(port), index, std::move(fd),
                           std::move(converted_planes));
}

void GpuArcVideoService::UseBuffer(::arc::mojom::PortType port,
                                   uint32_t index,
                                   ::arc::mojom::BufferMetadataPtr metadata) {
  DVLOG(2) << "UseBuffer port=" << port << ", index=" << index;
  accelerator_->UseBuffer(static_cast<PortType>(port), index,
                          metadata.To<BufferMetadata>());
}

void GpuArcVideoService::SetNumberOfOutputBuffers(uint32_t number) {
  DVLOG(2) << "SetNumberOfOutputBuffers number=" << number;
  accelerator_->SetNumberOfOutputBuffers(number);
}

void GpuArcVideoService::Reset() {
  DVLOG(2) << "Reset";
  accelerator_->Reset();
}

void GpuArcVideoService::Flush() {
  DVLOG(2) << "Flush";
  accelerator_->Flush();
}

}  // namespace arc
}  // namespace chromeos
