// Copyright 2019 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 "arc/vm/libvda/encode_wrapper.h"

#include <utility>

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/logging.h>

#include "arc/vm/libvda/encode/fake/fake_vea_impl.h"
#include "arc/vm/libvda/encode/gpu/gpu_vea_impl.h"

namespace arc {

VeaImpl::VeaImpl() {
  capabilities_.num_input_formats = 0;
  capabilities_.input_formats = nullptr;
  capabilities_.num_output_formats = 0;
  capabilities_.output_formats = nullptr;
}

VeaImpl::~VeaImpl() = default;

const vea_capabilities_t* const VeaImpl::GetCapabilities() {
  return &capabilities_;
}

VeaContext::VeaContext() = default;

VeaContext::~VeaContext() = default;

int VeaContext::GetEventFd() {
  return event_pipe_.GetReadFd();
}

void VeaContext::WriteEvent(const vea_event_t& event) {
  event_pipe_.WriteVeaEvent(event);
}

void VeaContext::DispatchRequireInputBuffers(uint32_t input_count,
                                             uint32_t input_frame_width,
                                             uint32_t input_frame_height,
                                             uint32_t output_buffer_size) {
  vea_event_t event;
  event.event_type = REQUIRE_INPUT_BUFFERS;
  event.event_data.require_input_buffers.input_count = input_count;
  event.event_data.require_input_buffers.input_frame_width = input_frame_width;
  event.event_data.require_input_buffers.input_frame_height =
      input_frame_height;
  event.event_data.require_input_buffers.output_buffer_size =
      output_buffer_size;
  WriteEvent(event);
}

void VeaContext::DispatchProcessedInputBuffer(
    vea_input_buffer_id_t input_buffer_id) {
  vea_event_t event;
  event.event_type = PROCESSED_INPUT_BUFFER;
  event.event_data.processed_input_buffer_id = input_buffer_id;
  WriteEvent(event);
}

void VeaContext::DispatchProcessedOutputBuffer(
    vea_output_buffer_id_t output_buffer_id,
    uint32_t payload_size,
    bool key_frame,
    int64_t timestamp) {
  vea_event_t event;
  event.event_type = PROCESSED_OUTPUT_BUFFER;
  event.event_data.processed_output_buffer.output_buffer_id = output_buffer_id;
  event.event_data.processed_output_buffer.payload_size = payload_size;
  event.event_data.processed_output_buffer.key_frame = key_frame;
  event.event_data.processed_output_buffer.timestamp = timestamp;
  WriteEvent(event);
}

void VeaContext::DispatchFlushResponse(bool flush_done) {
  vea_event_t event;
  event.event_type = VEA_FLUSH_RESPONSE;
  event.event_data.flush_done = flush_done;
  WriteEvent(event);
}

void VeaContext::DispatchNotifyError(vea_error_t error) {
  vea_event_t event;
  event.event_type = VEA_NOTIFY_ERROR;
  event.event_data.error = error;
  WriteEvent(event);
}

}  // namespace arc

void* initialize_encode(vea_impl_type_t impl_type) {
  switch (impl_type) {
    case VEA_FAKE:
      return arc::FakeVeaImpl::Create();
    case GAVEA: {
      arc::VafConnection* conn = arc::VafConnection::Get();
      if (conn == nullptr) {
        LOG(ERROR) << "Failed to retrieve VAF connection.";
        return nullptr;
      }
      return arc::GpuVeaImpl::Create(conn);
    }
    default:
      LOG(ERROR) << "Unknown impl type " << impl_type;
      return nullptr;
  }
}

void deinitialize_encode(void* impl) {
  arc::VeaImpl* cast_impl = static_cast<arc::VeaImpl*>(impl);
  delete cast_impl;
}

vea_session_info_t* init_encode_session(void* impl, vea_config_t* config) {
  arc::VeaContext* context =
      static_cast<arc::VeaImpl*>(impl)->InitEncodeSession(config);
  if (!context)
    return nullptr;
  vea_session_info_t* session_info = new vea_session_info_t();
  session_info->ctx = context;
  session_info->event_pipe_fd = context->GetEventFd();
  return session_info;
}

void close_encode_session(void* impl, vea_session_info_t* session_info) {
  static_cast<arc::VeaImpl*>(impl)->CloseEncodeSession(
      static_cast<arc::VeaContext*>(session_info->ctx));
  delete session_info;
}

const vea_capabilities_t* get_vea_capabilities(void* impl) {
  return static_cast<arc::VeaImpl*>(impl)->GetCapabilities();
}

int vea_encode(void* ctx,
               vea_input_buffer_id_t input_buffer_id,
               int fd,
               size_t num_planes,
               video_frame_plane_t* planes,
               int64_t timestamp,
               uint8_t force_keyframe) {
  return static_cast<arc::VeaContext*>(ctx)->Encode(
      input_buffer_id, base::ScopedFD(fd), num_planes, planes, timestamp,
      force_keyframe);
}

int vea_use_output_buffer(void* ctx,
                          vea_output_buffer_id_t output_buffer_id,
                          int fd,
                          uint32_t offset,
                          uint32_t size) {
  return static_cast<arc::VeaContext*>(ctx)->UseOutputBuffer(
      output_buffer_id, base::ScopedFD(fd), offset, size);
}

int vea_request_encoding_params_change(void* ctx,
                                       uint32_t bitrate,
                                       uint32_t framerate) {
  return static_cast<arc::VeaContext*>(ctx)->RequestEncodingParamsChange(
      bitrate, framerate);
}

int vea_flush(void* ctx) {
  return static_cast<arc::VeaContext*>(ctx)->Flush();
}
