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

#include <lib/fit/result.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include "src/camera/drivers/controller/configs/internal_config.h"
#include "src/lib/fsl/handles/object_info.h"

namespace camera {

constexpr auto kTag = "camera_controller_graph_helper";

const InternalConfigNode* GetNextNodeInPipeline(const fuchsia::camera2::CameraStreamType& stream,
                                                const InternalConfigNode& node) {
  for (const auto& child_node : node.child_nodes) {
    for (uint32_t i = 0; i < child_node.supported_streams.size(); i++) {
      if (child_node.supported_streams[i].type == stream) {
        return &child_node;
      }
    }
  }
  return nullptr;
}

fit::result<fuchsia::sysmem::BufferCollectionInfo_2, zx_status_t> GetClientBuffer(
    StreamCreationData* info) {
  for (uint32_t i = 0; i < info->output_buffers.buffer_count; i++) {
    std::string buffer_collection_name = "camera_controller_output_node";
    auto buffer_name = buffer_collection_name.append(std::to_string(i));
    fsl::MaybeSetObjectName(
        info->output_buffers.buffers[i].vmo.get(), buffer_name,
        [](std::string s) { return s.find("Sysmem") == 0 || s.find("ImagePipe2") == 0; });
  }
  return fit::ok(fidl::Clone(info->output_buffers));
}

fit::result<fuchsia::sysmem::BufferCollectionInfo_2, zx_status_t> GetBuffers(
    const ControllerMemoryAllocator& memory_allocator, const InternalConfigNode& producer,
    StreamCreationData* info, const std::string& buffer_tag) {
  fuchsia::sysmem::BufferCollectionInfo_2 buffers;
  const auto* consumer = GetNextNodeInPipeline(info->stream_type(), producer);
  auto current_producer = &producer;

  if (!consumer) {
    FX_LOGST(ERROR, kTag) << "Failed to get next node";
    return fit::error(ZX_ERR_INTERNAL);
  }

  // The controller might need to allocate memory using sysmem.
  // Populate the constraints.
  std::vector<fuchsia::sysmem::BufferCollectionConstraints> constraints;
  constraints.push_back(producer.output_constraints);

  while (consumer->in_place) {
    if (current_producer->child_nodes.size() != 1) {
      FX_LOGST(ERROR, kTag)
          << "Invalid configuration. A buffer is shared with a node which does in place operations";
      return fit::error(ZX_ERR_BAD_STATE);
    }
    constraints.push_back(consumer->input_constraints);
    current_producer = consumer;
    consumer = &consumer->child_nodes[0];
  };

  // If the consumer is the client, we use the client buffers.
  if (consumer->type == kOutputStream) {
    return GetClientBuffer(info);
  }

  for (const auto& node : current_producer->child_nodes) {
    if (node.type != kOutputStream) {
      constraints.push_back(node.input_constraints);
    }
  }

  auto status = memory_allocator.AllocateSharedMemory(constraints, &buffers, buffer_tag);
  if (status != ZX_OK) {
    FX_PLOGS(ERROR, status) << "Failed to allocate shared memory";
    return fit::error(status);
  }

  return fit::ok(std::move(buffers));
}

}  // namespace camera
