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

#include <lib/syslog/global.h>
#include <lib/trace/event.h>
#include <zircon/errors.h>

#include "src/lib/fsl/handles/object_info.h"

namespace camera {

constexpr auto kTag = "camera_controller";

ControllerMemoryAllocator::ControllerMemoryAllocator(
    fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator)
    : sysmem_allocator_(std::move(sysmem_allocator)) {
  if (sysmem_allocator_)
    sysmem_allocator_->SetDebugClientInfo("camera controller " + fsl::GetCurrentProcessName(),
                                          fsl::GetCurrentProcessKoid());
}

zx_status_t ControllerMemoryAllocator::AllocateSharedMemory(
    const std::vector<fuchsia::sysmem::BufferCollectionConstraints>& constraints,
    fuchsia::sysmem::BufferCollectionInfo_2* out_buffer_collection_info, std::string name) const {
  TRACE_DURATION("camera", "ControllerMemoryAllocator::AllocateSharedMemory");
  if (out_buffer_collection_info == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }

  auto num_constraints = constraints.size();

  // Create tokens which we'll hold on to to get our buffer_collection.
  std::vector<fuchsia::sysmem::BufferCollectionTokenSyncPtr> tokens(num_constraints);

  // Start the allocation process.
  auto status = sysmem_allocator_->AllocateSharedCollection(tokens[0].NewRequest());
  if (status != ZX_OK) {
    FX_LOG(ERROR, kTag, "Failed to create token");
    return status;
  }

  // Duplicate the tokens.
  for (uint32_t i = 1; i < num_constraints; i++) {
    status = tokens[0]->Duplicate(std::numeric_limits<uint32_t>::max(), tokens[i].NewRequest());
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Failed to duplicate token");
      return status;
    }
  }

  // Now convert into a Logical BufferCollection:
  std::vector<fuchsia::sysmem::BufferCollectionSyncPtr> buffer_collections(num_constraints);

  status = sysmem_allocator_->BindSharedCollection(std::move(tokens[0]),
                                                   buffer_collections[0].NewRequest());
  if (status != ZX_OK) {
    FX_LOG(ERROR, kTag, "Failed to create logical buffer collection");
    return status;
  }

  status = buffer_collections[0]->Sync();
  if (status != ZX_OK) {
    FX_LOG(ERROR, kTag, "Failed to sync");
    return status;
  }

  constexpr uint32_t kNamePriority = 10u;
  buffer_collections[0]->SetName(kNamePriority, name);

  // Create rest of the logical buffer collections
  for (uint32_t i = 1; i < num_constraints; i++) {
    status = sysmem_allocator_->BindSharedCollection(std::move(tokens[i]),
                                                     buffer_collections[i].NewRequest());
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Failed to create logical buffer collection");
      return status;
    }
  }

  // Set constraints
  for (uint32_t i = 0; i < num_constraints; i++) {
    status = buffer_collections[i]->SetConstraints(true, constraints[i]);
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Failed to set buffer collection constraints");
      return status;
    }
  }

  zx_status_t allocation_status;
  status = buffer_collections[0]->WaitForBuffersAllocated(&allocation_status,
                                                          out_buffer_collection_info);
  if (status != ZX_OK || allocation_status != ZX_OK) {
    FX_LOG(ERROR, kTag, "Failed to wait for buffer collection info.");
    return status;
  }

  for (uint32_t i = 0; i < num_constraints; i++) {
    status = buffer_collections[i]->Close();
    if (status != ZX_OK) {
      FX_LOG(ERROR, kTag, "Failed to close producer buffer collection");
      return status;
    }
  }

  // TODO(fxbug.dev/38569): Keep at least one buffer collection around to know about
  // any failures sysmem wants to notify by closing the channel.
  return ZX_OK;
}

}  // namespace camera
