// 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/controller/gdc_node.h"

#include <lib/syslog/cpp/macros.h>
#include <lib/trace/event.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <fbl/auto_call.h>
#include <safemath/safe_conversions.h>

#include "src/camera/drivers/controller/graph_utils.h"
#include "src/camera/drivers/controller/stream_pipeline_info.h"
#include "src/camera/lib/format_conversion/buffer_collection_helper.h"
#include "src/devices/lib/sysmem/sysmem.h"

namespace camera {

constexpr auto kTag = "camera_controller_gdc_node";

fit::result<gdc_config_info, zx_status_t> LoadGdcConfiguration(
    zx_device_t* device, ProductConfig& product_config, const camera::GdcConfig& config_type) {
  if (config_type == GdcConfig::INVALID) {
    FX_LOGST(DEBUG, kTag) << "Invalid GDC configuration type";
    return fit::error(ZX_ERR_INVALID_ARGS);
  }

  gdc_config_info info;
  size_t size;
  auto status =
      load_firmware(device, product_config.GetGdcConfigFile(config_type), &info.config_vmo, &size);
  if (status != ZX_OK || size == 0) {
    FX_PLOGST(ERROR, kTag, status) << "Failed to load the GDC firmware";
    return fit::error(status);
  }
  info.size = safemath::checked_cast<uint32_t>(size);
  return fit::ok(info);
}

void OnGdcFrameAvailable(void* ctx, const frame_available_info_t* info) {
  auto nonce = TRACE_NONCE();
  TRACE_DURATION("camera", "OnGdcFrameAvailable");
  TRACE_FLOW_BEGIN("camera", "post_gdc_frame_available", nonce);
  // This method is invoked by the GDC in its own thread,
  // so the event must be marshalled to the
  // controller's thread.
  auto* gdc_node = static_cast<GdcNode*>(ctx);
  gdc_node->RunOnMainThread([gdc_node, nonce, info = *info]() {
    TRACE_DURATION("camera", "OnGdcFrameAvailable.task");
    TRACE_FLOW_END("camera", "post_gdc_frame_available", nonce);
    gdc_node->OnFrameAvailable(&info);
  });
}

void OnGdcResChange(void* ctx, const frame_available_info_t* info) {
  static_cast<camera::ProcessNode*>(ctx)->OnResolutionChanged(info);
}

fit::result<ProcessNode*, zx_status_t> GdcNode::CreateGdcNode(
    const ControllerMemoryAllocator& memory_allocator, async_dispatcher_t* dispatcher,
    zx_device_t* device, const ddk::GdcProtocolClient& gdc, StreamCreationData* info,
    ProcessNode* parent_node, const InternalConfigNode& internal_gdc_node) {
  auto& input_buffers_hlcpp = parent_node->output_buffer_collection();
  auto result = GetBuffers(memory_allocator, internal_gdc_node, info, kTag);
  if (result.is_error()) {
    FX_LOGST(ERROR, kTag) << "Failed to get buffers";
    return fit::error(result.error());
  }

  auto output_buffers_hlcpp = std::move(result.value());

  BufferCollectionHelper output_buffer_collection_helper(output_buffers_hlcpp);
  BufferCollectionHelper input_buffer_collection_helper(input_buffers_hlcpp);

  // Convert the formats to C type
  std::vector<image_format_2_t> output_image_formats_c;
  for (const auto& format : internal_gdc_node.image_formats) {
    image_format_2_t value;
    auto original = GetImageFormatFromBufferCollection(*output_buffer_collection_helper.GetC(),
                                                       format.coded_width, format.coded_height);
    sysmem::image_format_2_banjo_from_fidl(original, value);
    output_image_formats_c.push_back(value);
  }

  // GDC only supports one input format and multiple output format at the
  // moment. So we take the first format from the previous node.
  // All existing usecases we support have only 1 format going into GDC.
  auto input_image_formats_c = GetImageFormatFromBufferCollection(
      *input_buffer_collection_helper.GetC(), parent_node->output_image_formats()[0].coded_width,
      parent_node->output_image_formats()[0].coded_height);

  // Get the GDC configurations loaded
  auto product_config = ProductConfig::Create();
  std::vector<gdc_config_info> config_vmos_info;
  for (const auto& config : internal_gdc_node.gdc_info.config_type) {
    auto gdc_config = LoadGdcConfiguration(device, *product_config, config);
    if (gdc_config.is_error()) {
      FX_LOGST(ERROR, kTag) << "Failed to load GDC configuration";
      return fit::error(gdc_config.error());
    }
    config_vmos_info.push_back(gdc_config.value());
  }

  auto cleanup = fbl::MakeAutoCall([config_vmos_info]() {
    for (auto info : config_vmos_info) {
      ZX_ASSERT_MSG(ZX_OK == zx_handle_close(info.config_vmo), "Failed to free up Config VMOs");
    }
  });

  // Create GDC Node
  auto gdc_node = std::make_unique<camera::GdcNode>(dispatcher, gdc, parent_node, internal_gdc_node,
                                                    std::move(output_buffers_hlcpp),
                                                    info->stream_type(), info->image_format_index);
  if (!gdc_node) {
    FX_LOGST(ERROR, kTag) << "Failed to create GDC node";
    return fit::error(ZX_ERR_NO_MEMORY);
  }

  // Initialize the GDC to get a unique task index
  uint32_t gdc_task_index;
  buffer_collection_info_2 temp_input_collection, temp_output_collection;
  image_format_2_t temp_image_format;
  sysmem::buffer_collection_info_2_banjo_from_fidl(*input_buffer_collection_helper.GetC(),
                                                   temp_input_collection);
  sysmem::buffer_collection_info_2_banjo_from_fidl(*output_buffer_collection_helper.GetC(),
                                                   temp_output_collection);
  sysmem::image_format_2_banjo_from_fidl(input_image_formats_c, temp_image_format);
  auto status = gdc.InitTask(
      &temp_input_collection, &temp_output_collection, &temp_image_format,
      output_image_formats_c.data(), output_image_formats_c.size(), info->image_format_index,
      config_vmos_info.data(), config_vmos_info.size(), gdc_node->frame_callback(),
      gdc_node->res_callback(), gdc_node->remove_task_callback(), &gdc_task_index);
  if (status != ZX_OK) {
    FX_PLOGST(ERROR, kTag, status) << "Failed to initialize GDC";
    return fit::error(status);
  }

  gdc_node->set_task_index(gdc_task_index);

  // Add child node.
  auto return_value = fit::ok(gdc_node.get());
  parent_node->AddChildNodeInfo(std::move(gdc_node));
  return return_value;
}

void GdcNode::OnFrameAvailable(const frame_available_info_t* info) {
  ZX_ASSERT(thread_checker_.is_thread_valid());
  TRACE_DURATION("camera", "GdcNode::OnFrameAvailable", "buffer_index", info->buffer_id);
  if (shutdown_requested_ || info->frame_status != FRAME_STATUS_OK) {
    return;
  }

  UpdateFrameCounterForAllChildren();

  if (NeedToDropFrame()) {
    parent_node_->OnReleaseFrame(info->metadata.input_buffer_index);
    gdc_.ReleaseFrame(task_index_, info->buffer_id);
    return;
  }
  // Free up parent's frame.
  parent_node_->OnReleaseFrame(info->metadata.input_buffer_index);
  ProcessNode::OnFrameAvailable(info);
}

void GdcNode::OnReleaseFrame(uint32_t buffer_index) {
  TRACE_DURATION("camera", "GdcNode::OnReleaseFrame", "buffer_index", buffer_index);
  fbl::AutoLock al(&in_use_buffer_lock_);
  ZX_ASSERT(buffer_index < in_use_buffer_count_.size());
  in_use_buffer_count_[buffer_index]--;
  if (in_use_buffer_count_[buffer_index] != 0) {
    return;
  }
  if (!shutdown_requested_) {
    gdc_.ReleaseFrame(task_index_, buffer_index);
  }
}

void GdcNode::OnReadyToProcess(const frame_available_info_t* info) {
  auto nonce = TRACE_NONCE();
  TRACE_DURATION("camera", "GdcNode::OnReadyToProcess");
  TRACE_FLOW_BEGIN("camera", "post_process_frame", nonce);
  async::PostTask(dispatcher_, [this, nonce, buffer_index = info->buffer_id,
                                capture_timestamp = info->metadata.capture_timestamp]() {
    TRACE_DURATION("camera", "GdcNode::OnReadyToProcess.task", "buffer_index", buffer_index);
    TRACE_FLOW_END("camera", "post_process_frame", nonce);
    if (enabled_) {
      ZX_ASSERT(ZX_OK == gdc_.ProcessFrame(task_index_, buffer_index, capture_timestamp));
    } else {
      // Since streaming is disabled the incoming frame is released
      // so it gets added back to the pool.
      parent_node_->OnReleaseFrame(buffer_index);
    }
  });
}

void GdcNode::OnTaskRemoved(zx_status_t status) {
  ZX_ASSERT(status == ZX_OK);
  async::PostTask(dispatcher_, [this]() {
    node_callback_received_ = true;
    OnCallbackReceived();
  });
}

void GdcNode::OnShutdown(fit::function<void(void)> shutdown_callback) {
  shutdown_callback_ = std::move(shutdown_callback);

  // After a shutdown request has been made,
  // no other calls should be made to the GDC driver.
  shutdown_requested_ = true;

  // Request GDC to shutdown.
  gdc_.RemoveTask(task_index_);

  auto child_shutdown_completion_callback = [this]() {
    child_node_callback_received_ = true;
    OnCallbackReceived();
  };

  ZX_ASSERT_MSG(configured_streams().size() == 1,
                "Cannot shutdown a stream which supports multiple streams");

  // Forward the shutdown request to child node.
  child_nodes().at(0)->OnShutdown(child_shutdown_completion_callback);
}

void GdcNode::OnResolutionChangeRequest(uint32_t output_format_index) {
  if (enabled_) {
    TRACE_DURATION("camera", "GdcNode::OnResolutionChangeRequest", "index", output_format_index);
    gdc_.SetOutputResolution(task_index_, output_format_index);
    set_current_image_format_index(output_format_index);
  }
}
}  // namespace camera
