// Copyright 2019 The Fuchsia 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 "src/camera/drivers/hw_accel/gdc/gdc_task.h"

#include <lib/syslog/global.h>
#include <stdint.h>
#include <zircon/types.h>

#include <memory>

#include <ddk/debug.h>

constexpr auto kTag = "gdc";

namespace gdc {

zx_status_t GdcTask::PinConfigVmos(const gdc_config_info* config_vmo_list, size_t config_vmos_count,
                                   const zx::bti& bti) {
  pinned_config_vmos_ =
      fbl::Array<fzl::PinnedVmo>(new fzl::PinnedVmo[config_vmos_count], config_vmos_count);

  for (uint32_t i = 0; i < config_vmos_count; i++) {
    zx::vmo vmo(config_vmo_list[i].config_vmo);
    if (!vmo.is_valid()) {
      return ZX_ERR_INVALID_ARGS;
    }

    uint64_t size;
    auto status = vmo.get_size(&size);
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Unable to get VMO size");
      return status;
    }

    zx::vmo contig_vmo;
    status = zx::vmo::create_contiguous(bti, size, 0, &contig_vmo);
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Unable to get create contiguous VMO");
      return status;
    }

    fzl::VmoMapper mapped_buffer_vmo;
    status = mapped_buffer_vmo.Map(vmo, 0, 0, ZX_VM_PERM_READ);
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Unable to get map VMO");
      return status;
    }

    fzl::VmoMapper mapped_buffer_contig_vmo;
    status = mapped_buffer_contig_vmo.Map(contig_vmo, 0, 0, ZX_VM_PERM_READ | ZX_VM_PERM_WRITE);
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Unable to get map contig VMO");
      return status;
    }

    memcpy(mapped_buffer_contig_vmo.start(), mapped_buffer_vmo.start(), size);

    // Clean and invalidate the contiguous VMO.
    status = contig_vmo.op_range(ZX_VMO_OP_CACHE_CLEAN, 0, size, nullptr, 0);
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Unable to clean and invalidate the cache");
      return status;
    }

    status = pinned_config_vmos_[i].Pin(contig_vmo, bti, ZX_BTI_CONTIGUOUS | ZX_VM_PERM_READ);
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Failed to pin config VMO");
      return status;
    }
    if (pinned_config_vmos_[i].region_count() != 1) {
      FX_LOG(ERROR, kTag, "Buffer is not contiguous");
      return ZX_ERR_NO_MEMORY;
    }

    gdc_config_info config_info;
    config_info.config_vmo = std::move(contig_vmo.release());
    config_info.size = config_vmo_list[i].size;
    config_contig_vmos_.push_back(std::move(config_info));

    // Release the vmos so that the handle doesn't get closed
    __UNUSED zx_handle_t handle = vmo.release();
  }
  return ZX_OK;
}

zx_status_t GdcTask::Init(const buffer_collection_info_2_t* input_buffer_collection,
                          const buffer_collection_info_2_t* output_buffer_collection,
                          const image_format_2_t* input_image_format,
                          const image_format_2_t* output_image_format_table_list,
                          size_t output_image_format_table_count,
                          uint32_t output_image_format_index,
                          const gdc_config_info* config_vmo_list, size_t config_vmos_count,
                          const hw_accel_frame_callback_t* frame_callback,
                          const hw_accel_res_change_callback_t* res_callback,
                          const hw_accel_remove_task_callback_t* remove_task_callback,
                          const zx::bti& bti) {
  if (frame_callback == nullptr || res_callback == nullptr || config_vmo_list == nullptr ||
      remove_task_callback == nullptr || config_vmos_count == 0 ||
      config_vmos_count != output_image_format_table_count ||
      (output_image_format_table_count < 1) ||
      (output_image_format_index >= output_image_format_table_count)) {
    return ZX_ERR_INVALID_ARGS;
  }

  zx_status_t status = PinConfigVmos(config_vmo_list, config_vmos_count, bti);
  if (status != ZX_OK) {
    FX_LOG(ERROR, kTag, "PinConfigVmo Failed");
    return status;
  }

  status = InitBuffers(input_buffer_collection, output_buffer_collection, input_image_format, 1, 0,
                       output_image_format_table_list, output_image_format_table_count,
                       output_image_format_index, bti, frame_callback, res_callback,
                       remove_task_callback);
  if (status != ZX_OK) {
    FX_LOG(ERROR, kTag, "InitBuffers Failed");
    return status;
  }

  return status;
}

}  // namespace gdc
