// 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.

#ifndef SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_LOGICAL_BUFFER_COLLECTION_H_
#define SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_LOGICAL_BUFFER_COLLECTION_H_

#include <fidl/fuchsia.sysmem2/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2/cpp/wire.h>
#include <inttypes.h>
#include <lib/async/cpp/task.h>
#include <lib/fidl/cpp/wire/arena.h>
#include <lib/sysmem-version/sysmem-version.h>
#include <lib/zx/channel.h>

#include <cstdint>
#include <list>
#include <map>
#include <memory>
#include <unordered_map>

#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <fbl/string_printf.h>

#include "src/devices/sysmem/drivers/sysmem/allocation_result.h"
#include "src/devices/sysmem/drivers/sysmem/device.h"
#include "src/devices/sysmem/drivers/sysmem/indent.h"
#include "src/devices/sysmem/drivers/sysmem/logging.h"
#include "src/devices/sysmem/drivers/sysmem/node_properties.h"
#include "src/devices/sysmem/drivers/sysmem/utils.h"
#include "src/devices/sysmem/drivers/sysmem/versions.h"

namespace sysmem_driver {

class BufferCollectionToken;
class BufferCollectionTokenGroup;
class BufferCollection;
class LogicalBuffer;
class LogicalBufferCollection;
class MemoryAllocator;
class Node;

// This class can be used to hold an inspect snapshot of one set of constraints taken from a client
// at a particular point in time.
struct ConstraintInfoSnapshot {
  inspect::Node inspect_node;
};

// Each TrackedParentVmo keeps the LogicalBufferCollection alive as long as there are child VMOs
// outstanding (no revoking of child VMOs for now).
//
// This tracking is for the benefit of MemoryAllocator sub-classes that need
// a Delete() call, such as to clean up a slab allocation and/or to inform
// an external allocator of delete.
class TrackedParentVmo {
 public:
  using DoDelete = fit::callback<void(TrackedParentVmo* parent)>;
  // The do_delete callback will be invoked upon the sooner of (A) the client code causing
  // ~TrackedParentVmo, or (B) ZX_VMO_ZERO_CHILDREN occurring async after StartWait() is called.
  //
  // Each TrackedParentVmo associated with a LogicalBufferCollection keeps the
  // LogicalBufferCollection alive. Once a (child) VMO has been given out by sysmem, the only
  // mechanism to delete TrackedParentVmo is ZX_VMO_ZERO_CHILDREN.
  TrackedParentVmo(fbl::RefPtr<LogicalBufferCollection> logical_buffer, zx::vmo vmo,
                   uint32_t buffer_index, DoDelete do_delete);
  ~TrackedParentVmo();

  // This should only be called after client code has created a child VMO, and will begin the wait
  // for ZX_VMO_ZERO_CHILDREN.
  zx_status_t StartWait(async_dispatcher_t* dispatcher);

  // Cancel the wait.
  zx_status_t CancelWait();

  zx::vmo TakeVmo();
  [[nodiscard]] const zx::vmo& vmo() const;

  void set_child_koid(zx_koid_t koid) {
    ZX_DEBUG_ASSERT(!child_koid_.has_value());
    child_koid_ = koid;
  }
  [[nodiscard]] std::optional<zx_koid_t> child_koid() const { return child_koid_; }

  void set_client_debug_info(ClientDebugInfo client_debug_info) {
    client_debug_info_ = client_debug_info;
  }
  [[nodiscard]] ClientDebugInfo* get_client_debug_info() {
    return client_debug_info_.has_value() ? &*client_debug_info_ : nullptr;
  }

  uint32_t buffer_index() { return buffer_index_; }

  // no copy, no move (async::WaitMethod isn't anyway, but just to be clear about it)
  TrackedParentVmo(const TrackedParentVmo&) = delete;
  TrackedParentVmo& operator=(const TrackedParentVmo&) = delete;
  TrackedParentVmo(TrackedParentVmo&&) = delete;
  TrackedParentVmo& operator=(TrackedParentVmo&&) = delete;

 private:
  void OnZeroChildren(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                      const zx_packet_signal_t* signal);
  fbl::RefPtr<LogicalBufferCollection> buffer_collection_;
  zx::vmo vmo_;
  const uint32_t buffer_index_ = 0x80000000;

  // For TrackedParentVmo(s) which are direct parents of sysmem-provided VMO(s), the child VMO's
  // koid is retained here for calling Device::RemoveVmoKoid later, since GetVmoInfo by definition
  // only asks about VMOs that have handles open (a handle is passed into GetVmoInfo which ensures
  // this).
  std::optional<zx_koid_t> child_koid_;

  // A TrackedParentVmo can outlast a Node, so own a copy here.
  std::optional<ClientDebugInfo> client_debug_info_;

  DoDelete do_delete_;

  async::WaitMethod<TrackedParentVmo, &TrackedParentVmo::OnZeroChildren> zero_children_wait_;

  // Only for asserts:
  bool waiting_ = {};
};

// This is all the per-VMO info and mechanism except for
// LogicalBufferCollection::allocation_result_info_, which we keep in sync with the set of
// LogicalBuffer(s) in LogicalBufferCollection::buffers_.
//
// This is always held in a std::unique_ptr<> instead of move-only because TrackedParentVmo
// do_delete callbacks within need to capture a non-moving LogicalBuffer. We use std::unique_ptr<>
// rather than shared_ptr<> or fbl::RefPtr<> because we need to ensure we can just delete all the
// buffers in buffers_ if LogicalBufferCollection::Allocate() fails to allocate a later buffer.
class LogicalBuffer {
 public:
  static fit::result<zx_status_t, std::unique_ptr<LogicalBuffer>> Create(
      fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection, uint32_t buffer_index,
      zx::vmo parent_vmo);
  fit::result<zx_status_t, std::optional<zx::vmo>> CreateWeakVmo(
      const ClientDebugInfo& client_debug_info);

  LogicalBufferCollection& logical_buffer_collection();
  uint32_t buffer_index();

  // Client code should take this VMO before moving LogicalBuffer from stack to heap.
  zx::vmo TakeStrongChildVmo();

  fit::result<zx_status_t, zx::eventpair> DupCloseWeakAsapClientEnd();

  // move-only
  LogicalBuffer(const LogicalBuffer& to_copy) = delete;
  LogicalBuffer& operator=(const LogicalBuffer& to_copy) = delete;
  LogicalBuffer(LogicalBuffer&& to_move) = default;
  LogicalBuffer& operator=(LogicalBuffer&& to_move) = default;

 private:
  friend class LogicalBufferCollection;

  LogicalBuffer(fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection,
                uint32_t buffer_index, zx::vmo parent_vmo);
  // true iff construction was successful
  bool is_ok();
  // requires !is_ok(); returns the failure status
  zx_status_t error();

  void ComplainLoudlyAboutStillExistingWeakVmoHandles();

  fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection_;
  uint32_t buffer_index_;

  // This is the allocator-provided VMO (parent-most VMO tracked by sysmem; the allocator itself
  // may keep a parent VMO of this VMO, but that further parent is not known to sysmem).
  //
  // When this sees ZX_VMO_ZERO_CHILDREN, we can tell the allocator to free the allocator's VMO and
  // reclaim the space. This also deletes parent_vmo_ and LogicalBuffer.
  std::unique_ptr<TrackedParentVmo> parent_vmo_;

  // This is a child VMO of parent_vmo_, and has as children all sysmem strong VMOs associated with
  // this LogicalBuffer.
  //
  // When this sees ZX_VMO_ZERO_CHILDREN, we can ask clients to close any remaining weak VMOs by
  // closing the server end of close_weak_asap, and we set a timer to complain loudly if the
  // LogicalBuffer still exists after a while, since this would essentially count as a client
  // leaking a VMO. This also deletes strong_parent_vmo_.
  std::unique_ptr<TrackedParentVmo> strong_parent_vmo_;

  // These are parents of each weak VMO that was sent to a client (separate parent for each sent
  // weak VMO).
  //
  // This map exists to keep each TrackedParentVmo alive until all its child VMOs are gone, and to
  // have a way to complain about specific sent child weak VMOs that still haven't closed a while
  // after all strong VMOs of a buffer_index have closed.
  //
  // The TrackedParentVmo's vmo has its name set based on client debug info.
  std::unordered_map<TrackedParentVmo*, std::unique_ptr<TrackedParentVmo>> weak_parent_vmos_;

  struct CloseWeakAsap {
    zx::eventpair server_end;
    zx::eventpair client_end;
  };
  // ~close_weak_asap_ will signal clients via ZX_EVENTPAIR_PEER_CLOSED. This gets deleted when
  // ~strong_parent_vmo_.
  std::optional<CloseWeakAsap> close_weak_asap_;
  bool close_weak_asap_created_ = false;
  // If there were any outstanding weak VMOs when *close_weak_asap_ was deleted, this is when
  // close_weak_asap_ was deleted, signalling clients via ZX_EVENTPAIR_PEER_CLOSED. If there were
  // no outstanding weak VMOs when close_weak_asap_ was deleted, we don't add tallies to
  // weak_vmo_histograms because we want the histograms to only include logical buffer collections
  // that had any weak VMOs that needed to be closed; this is to avoid a bunch of tallies for
  // strong-only collections adding a bunch of tally counts in low duration histogram buckets.
  std::optional<zx::time> close_weak_asap_time_;

  // Set to a failing status if LogicalBuffer::LogicalBuffer() failed.
  zx_status_t error_ = ZX_OK;

  zx::vmo strong_child_vmo_;
};

// TODO(dustingreen): MaybeAllocate() should sweep all related incoming channels for ZX_PEER_CLOSED
// and not attempt allocation until all channel close(es) that were pending at the time have been
// processed.  Ignoring new channel closes is fine/good.
class LogicalBufferCollection : public fbl::RefCounted<LogicalBufferCollection> {
 public:
  using Arena = fidl::Arena<>;
  using CollectionMap = std::map<BufferCollection*, fbl::RefPtr<BufferCollection>>;

  ~LogicalBufferCollection();

  static void CreateV1(TokenServerEndV1 buffer_collection_token_request, Device* parent_device,
                       const ClientDebugInfo* client_debug_info);
  static void CreateV2(TokenServerEndV2 buffer_collection_token_request, Device* parent_device,
                       const ClientDebugInfo* client_debug_info);

  // |parent_device| the Device* that the calling allocator is part of.  The
  // tokens_by_koid_ for each Device is separate.  If somehow two clients were
  // to get connected to two separate sysmem device instances hosted in the
  // same devhost, those clients (intentionally) won't be able to share a
  // LogicalBufferCollection.
  //
  // |buffer_collection_token| the client end of the BufferCollectionToken
  // being turned in by the client to get a BufferCollection in exchange.
  //
  // |buffer_collection_request| the server end of a BufferCollection channel
  // to be served by the LogicalBufferCollection associated with
  // buffer_collection_token.
  static void BindSharedCollection(Device* parent_device, zx::channel buffer_collection_token,
                                   CollectionServerEnd buffer_collection_request,
                                   const ClientDebugInfo* client_debug_info);

  // ZX_OK if the token is known to the server.
  // ZX_ERR_NOT_FOUND if the token isn't known to the server.
  static zx_status_t ValidateBufferCollectionToken(Device* parent_device,
                                                   zx_koid_t token_server_koid);

  // This is used to create the initial BufferCollectionToken, and also used
  // by BufferCollectionToken::Duplicate().
  //
  // The |self| parameter exists only because LogicalBufferCollection can't
  // hold a std::weak_ptr<> to itself because that requires libc++ (the binary
  // not just the headers) which isn't available in Zircon so far.
  void CreateBufferCollectionTokenV1(fbl::RefPtr<LogicalBufferCollection> self,
                                     NodeProperties* new_node_properties,
                                     TokenServerEndV1 token_request);
  void CreateBufferCollectionTokenV2(fbl::RefPtr<LogicalBufferCollection> self,
                                     NodeProperties* new_node_properties,
                                     TokenServerEndV2 token_request);

  // This is used by BufferCollectionToken to create a BufferCollectionTokenGroup during the
  // FIDL request of the same name.
  void CreateBufferCollectionTokenGroupV1(fbl::RefPtr<LogicalBufferCollection> self,
                                          NodeProperties* new_node_properties,
                                          GroupServerEndV1 group_request);
  void CreateBufferCollectionTokenGroupV2(fbl::RefPtr<LogicalBufferCollection> self,
                                          NodeProperties* new_node_properties,
                                          GroupServerEndV2 group_request);
  bool CommonCreateBufferCollectionTokenGroupStage1(fbl::RefPtr<LogicalBufferCollection> self,
                                                    NodeProperties* new_node_properties,
                                                    const GroupServerEnd& group_request,
                                                    BufferCollectionTokenGroup** out_group);

  void AttachLifetimeTracking(zx::eventpair server_end, uint32_t buffers_remaining);
  void SweepLifetimeTracking();

  // Calling this extra times (including after allocation complete) isn't harmful from a correctness
  // point of view.
  void OnDependencyReady();

  void SetName(uint32_t priority, std::string name);
  void SetDebugTimeoutLogDeadline(int64_t deadline);
  void SetVerboseLogging();

  uint64_t CreateDispensableOrdinal();

  void VLogClient(bool is_error, Location location, const NodeProperties* node_properties,
                  const char* format, va_list args) const;
  void LogClientInfo(Location location, const NodeProperties* node_properties, const char* format,
                     ...) const __PRINTFLIKE(4, 5);
  void LogClientError(Location location, const NodeProperties* node_properties, const char* format,
                      ...) const __PRINTFLIKE(4, 5);
  void VLogClientInfo(Location location, const NodeProperties* node_properties, const char* format,
                      va_list args) const;
  void VLogClientError(Location location, const NodeProperties* node_properties, const char* format,
                       va_list args) const;

  Device* parent_device() const { return parent_device_; }

  // For tests.
  std::vector<const BufferCollection*> collection_views() const;

  // Track/untrack the node by the koid of the client end of its FIDL channel.
  //
  // While tracked, a node can be found with FindNodeByClientChannelKoid().
  //
  // Only is_currently_connected() true Node(s) are tracked.
  //
  // Aside from this tracking, LogicalBufferCollection only cares about NodeProperties, not Nodes,
  // but since we need to track by client_koid which is a Node-specific thing, this tracking allows
  // for that.
  //
  // This tracking exists for the benefit of IsAlternateFor(), which is essentially called on one
  // node and refers to another node by client endpoint koid, which must be owned by the same
  // process as the calling node.
  void TrackNodeProperties(NodeProperties* node_properties);
  void UntrackNodeProperties(NodeProperties* node_properties);
  std::optional<NodeProperties*> FindNodePropertiesByNodeRefKoid(zx_koid_t node_ref_keep_koid);

  std::optional<std::string> name() const {
    return name_.has_value() ? std::make_optional(name_->name) : std::nullopt;
  }

  inspect::Node& inspect_node() { return inspect_node_; }

  bool is_verbose_logging() const { return is_verbose_logging_; }

  uint64_t buffer_collection_id() const { return buffer_collection_id_; }

  static fit::result<zx_status_t, BufferCollectionToken*> CommonConvertToken(
      Device* parent_device, zx::channel buffer_collection_token,
      const ClientDebugInfo* client_debug_info, const char* fidl_message_name);

  fit::result<zx_status_t, std::optional<zx::vmo>> CreateWeakVmo(
      uint32_t buffer_index, const ClientDebugInfo& client_debug_info);
  fit::result<zx_status_t, std::optional<zx::eventpair>> DupCloseWeakAsapClientEnd(
      uint32_t buffer_index);

  void LogSummary(IndentTracker& indent);

  zx::time create_time_monotonic() const { return create_time_monotonic_; }

 private:
  friend class LogicalBuffer;
  friend class NodeProperties;
  friend class TrackedParentVmo;

  enum class CheckSanitizeStage { kInitial, kNotAggregated, kAggregated };

  class Constraints {
   public:
    Constraints(const Constraints&) = delete;
    Constraints(Constraints&&) = default;
    Constraints(fuchsia_sysmem2::BufferCollectionConstraints constraints,
                const NodeProperties& node_properties)
        : buffer_collection_constraints_(std::move(constraints)),
          node_properties_(node_properties) {}

    const fuchsia_sysmem2::BufferCollectionConstraints& constraints() const {
      return buffer_collection_constraints_;
    }
    fuchsia_sysmem2::BufferCollectionConstraints& mutate_constraints() {
      return buffer_collection_constraints_;
    }

    const ClientDebugInfo& client_debug_info() const {
      return node_properties_.client_debug_info();
    }
    const NodeProperties& node_properties() const { return node_properties_; }

   private:
    fuchsia_sysmem2::BufferCollectionConstraints buffer_collection_constraints_;
    const NodeProperties& node_properties_;
  };

  using ConstraintsList = std::list<Constraints>;

  struct CollectionName {
    uint32_t priority{};
    std::string name;
  };

  explicit LogicalBufferCollection(Device* parent_device);

  // Will log an error, and then FailRoot().
  void LogAndFailRootNode(Location location, fuchsia_sysmem2::Error error, const char* format, ...)
      __PRINTFLIKE(4, 5);
  // This fails the entire LogicalBufferCollection, by failing the root Node, which propagates that
  // failure to the entire Node tree, and also results in zero remaining Node(s).  Then once all
  // outstanding VMOs have been closed, the LogicalBufferCollection is deleted.
  //
  // This cleans out a lot of state that's unnecessary after a failure.
  void FailRootNode(fuchsia_sysmem2::Error error);

  NodeProperties* FindTreeToFail(NodeProperties* failing_node);

  // Fails the tree rooted at tree_to_fail.  The tree_to_fail is allowed to be the root_, or it can
  // be a sub-tree. All the Node(s) from tree_to_fail down are Fail()ed.  Any sysmem(1) Node(s) that
  // still have channels open will send epitaph. Sysmem2 Node(s) always send ZX_ERR_INTERNAL as the
  // epitaph (mainly because an epitaph is required by FIDL bindings). In either case the channel is
  // closed. All Node(s) from tree_to_fail downward are also removed from the tree. If tree_to_fail
  // is the root, then when all child VMOs have been closed, the LogicalBufferCollection will be
  // deleted.
  //
  // Node(s) are Fail()ed and removed from the tree in child-first order.
  //
  // These two are only appropriate to use if it's already known which node should fail.  If it's
  // not yet known which node should fail, call FindTreeToFail() first, or use LogAndFailNode() /
  // FailNode().
  void LogAndFailDownFrom(Location location, NodeProperties* tree_to_fail,
                          fuchsia_sysmem2::Error error, const char* format, ...) __PRINTFLIKE(5, 6);
  void FailDownFrom(NodeProperties* tree_to_fail, fuchsia_sysmem2::Error error);

  // Find the root-most node of member_node's failure domain, and fail that whole failure domain and
  // any of its child failure domains.
  void LogAndFailNode(Location location, NodeProperties* member_node, fuchsia_sysmem2::Error error,
                      const char* format, ...) __PRINTFLIKE(5, 6);
  void FailNode(NodeProperties* member_node, fuchsia_sysmem2::Error error);

  void LogInfo(Location location, const char* format, ...) const;
  static void LogErrorStatic(Location location, const ClientDebugInfo* client_debug_info,
                             const char* format, ...) __PRINTFLIKE(3, 4);

  void LogError(Location location, const char* format, ...) const __PRINTFLIKE(3, 4);
  void VLogError(Location location, const char* format, va_list args) const;

  void ResetGroupChildSelection(std::vector<NodeProperties*>& groups_by_priority);
  void InitGroupChildSelection(std::vector<NodeProperties*>& groups_by_priority);
  void NextGroupChildSelection(std::vector<NodeProperties*> groups_by_priority);
  bool DoneWithGroupChildSelections(std::vector<NodeProperties*> groups_by_priority);

  // The caller must keep "this" alive.  We require this of the caller since the caller is fairly
  // likely to want to keep "this" alive longer than MaybeAllocate() could anyway.
  void MaybeAllocate();

  fpromise::result<fuchsia_sysmem2::BufferCollectionInfo, fuchsia_sysmem2::Error> TryAllocate(
      std::vector<NodeProperties*> nodes);

  std::optional<fuchsia_sysmem2::Error> TryLateLogicalAllocation(
      std::vector<NodeProperties*> nodes);

  zx::result<bool> CompareBufferCollectionInfo(fuchsia_sysmem2::BufferCollectionInfo& lhs,
                                               fuchsia_sysmem2::BufferCollectionInfo& rhs);

  void InitializeConstraintSnapshots(const ConstraintsList& constraints_list);

  void SetFailedAllocationResult(fuchsia_sysmem2::Error error);

  void SetAllocationResult(std::vector<NodeProperties*> visible_pruned_sub_tree,
                           fuchsia_sysmem2::BufferCollectionInfo info,
                           std::vector<NodeProperties*> whole_pruned_sub_tree);

  void SendAllocationResult(std::vector<NodeProperties*> nodes);

  void SetFailedLateLogicalAllocationResult(NodeProperties* tree,
                                            fuchsia_sysmem2::Error status_param);

  void SetSucceededLateLogicalAllocationResult(std::vector<NodeProperties*> visible_pruned_sub_tree,
                                               std::vector<NodeProperties*> whole_pruned_sub_tree);

  void BindSharedCollectionInternal(BufferCollectionToken* token,
                                    CollectionServerEnd buffer_collection_request);

  fpromise::result<fuchsia_sysmem2::BufferCollectionConstraints, void> CombineConstraints(
      ConstraintsList* constraints_list);

  bool CheckSanitizeBufferCollectionConstraints(
      CheckSanitizeStage stage, fuchsia_sysmem2::BufferCollectionConstraints& constraints);

  bool CheckSanitizeBufferUsage(CheckSanitizeStage stage,
                                fuchsia_sysmem2::BufferUsage& buffer_usage);

  bool CheckSanitizeHeap(CheckSanitizeStage stage, fuchsia_sysmem2::Heap& heap);

  bool CheckSanitizeBufferMemoryConstraints(CheckSanitizeStage stage,
                                            const fuchsia_sysmem2::BufferUsage& buffer_usage,
                                            fuchsia_sysmem2::BufferMemoryConstraints& constraints);

  bool CheckSanitizeImageFormatConstraints(CheckSanitizeStage stage,
                                           const fuchsia_sysmem2::BufferUsage& buffer_usage,
                                           fuchsia_sysmem2::ImageFormatConstraints& constraints);

  bool AccumulateConstraintBufferCollection(fuchsia_sysmem2::BufferCollectionConstraints* acc,
                                            fuchsia_sysmem2::BufferCollectionConstraints c);

  bool AccumulateConstraintsBufferUsage(fuchsia_sysmem2::BufferUsage* acc,
                                        fuchsia_sysmem2::BufferUsage c);

  bool AccumulateConstraintPermittedHeaps(std::vector<fuchsia_sysmem2::Heap>* acc,
                                          std::vector<fuchsia_sysmem2::Heap> c);

  bool AccumulateConstraintBufferMemory(fuchsia_sysmem2::BufferMemoryConstraints* acc,
                                        fuchsia_sysmem2::BufferMemoryConstraints c);

  bool AccumulateConstraintImageFormats(std::vector<fuchsia_sysmem2::ImageFormatConstraints>* acc,
                                        std::vector<fuchsia_sysmem2::ImageFormatConstraints> c);

  bool AccumulateConstraintImageFormat(fuchsia_sysmem2::ImageFormatConstraints* acc,
                                       fuchsia_sysmem2::ImageFormatConstraints c);

  bool AccumulateConstraintColorSpaces(std::vector<fuchsia_images2::ColorSpace>* acc,
                                       std::vector<fuchsia_images2::ColorSpace> c);

  size_t InitialCapacityOrZero(CheckSanitizeStage stage, size_t initial_capacity);

  bool IsColorSpaceEqual(const fuchsia_images2::ColorSpace& a,
                         const fuchsia_images2::ColorSpace& b);

  fpromise::result<fuchsia_sysmem2::BufferCollectionInfo, zx_status_t>
  GenerateUnpopulatedBufferCollectionInfo(
      const fuchsia_sysmem2::BufferCollectionConstraints& constraints);

  fpromise::result<fuchsia_sysmem2::BufferCollectionInfo, fuchsia_sysmem2::Error> Allocate(
      const fuchsia_sysmem2::BufferCollectionConstraints& constraints,
      fuchsia_sysmem2::BufferCollectionInfo* buffer_collection_info);

  fpromise::result<zx::vmo> AllocateVmo(MemoryAllocator* allocator,
                                        const fuchsia_sysmem2::SingleBufferSettings& settings,
                                        uint32_t index);

  int32_t CompareImageFormatConstraintsTieBreaker(const fuchsia_sysmem2::ImageFormatConstraints& a,
                                                  const fuchsia_sysmem2::ImageFormatConstraints& b);

  int32_t CompareImageFormatConstraintsByIndex(
      const fuchsia_sysmem2::BufferCollectionConstraints& constraints, uint32_t index_a,
      uint32_t index_b);

  void CreationTimedOut(async_dispatcher_t* dispatcher, async::TaskBase* task, zx_status_t status);

  AllocationResult allocation_result();

  void LogBufferCollectionInfoDiffs(const fuchsia_sysmem2::BufferCollectionInfo& o,
                                    const fuchsia_sysmem2::BufferCollectionInfo& n);

  // To be called only by CombineConstraints().
  bool IsMinBufferSizeSpecifiedByAnyParticipant(const ConstraintsList& constraints_list);

  // This is the root and any sub-trees created via SetDispensable() or AttachToken().
  std::vector<NodeProperties*> FailureDomainSubtrees();

  // A Node is a pruned sub-tree eligible for logical allocation if it is not yet logically
  // allocated, and does not have a non-logically-allocated direct parent.
  //
  // Such sub-trees will always have a root-most Node that is either the root or an
  // ErrorPropagationMode kDoNotPropagate Node.
  //
  // The returned pruned sub-trees may not be ready for logical allocation (may not have all its
  // constraints yet), nor do they necessarily have constraints that are satisfiable.
  std::vector<NodeProperties*> PrunedSubtreesEligibleForLogicalAllocation();

  // The granularity of logical allocation is a sub-tree pruned of any ErrorPropagationMode
  // kDoNotPropagate Node(s) other than the sub-tree's root-most node.
  //
  // The root-most Node of a pruned subtree can be the root, or it can be a Node that has
  // ErrorPropagationMode kDoNotPropagate (implying that AttachToken() was used to create the
  // non-root Node).
  //
  // The pruning is the same for both the root and a non-root Node so that the locally-observable
  // (by a participant) logical allocation granularity is the same regardless of whether the logical
  // allocation granule has the root as its root-most Node, or has an ErrorPropagationMode
  // kDoNotPropagate Node as its root-most Node.
  std::vector<NodeProperties*> NodesOfPrunedSubtreeEligibleForLogicalAllocation(
      NodeProperties& subtree);

  std::vector<NodeProperties*> PrioritizedGroupsOfPrunedSubtreeEligibleForLogicalAllocation(
      NodeProperties& subtree);

  // For NodeProperties:
  void AddCountsForNode(const Node& node);
  void RemoveCountsForNode(const Node& node);
  void AdjustRelevantNodeCounts(const Node& node, fit::function<void(uint32_t& count)> visitor);
  void DeleteRoot();

  // Diff printing.

#if defined(PRINT_DIFF)
#error "Let's pick a different name for PRINT_DIFF"
#endif
  // If LLCPP had generic field objects, we wouldn't need this macro.  We #undef the macro name
  // after we're done using it so it doesn't escape this header.
#define PRINT_DIFF(child_field_name)                                                               \
  do {                                                                                             \
    const std::string& parent_field_name = field_name;                                             \
    if (o.child_field_name().has_value() != n.child_field_name().has_value()) {                    \
      LogError(FROM_HERE,                                                                          \
               "o%s." #child_field_name                                                            \
               "().has_value(): %d "                                                               \
               "n%s." #child_field_name "().has_value(): %d",                                      \
               parent_field_name.c_str(), o.child_field_name().has_value(),                        \
               parent_field_name.c_str(), n.child_field_name().has_value());                       \
    } else if (o.child_field_name().has_value()) {                                                 \
      std::string field_name =                                                                     \
          fbl::StringPrintf("%s.%s()", parent_field_name.c_str(), #child_field_name).c_str();      \
      DiffPrinter<std::remove_const_t<std::remove_reference_t<decltype(*o.child_field_name())>>>:: \
          PrintDiff(*this, field_name, *o.child_field_name(), *n.child_field_name());              \
    }                                                                                              \
  } while (false)

  template <typename FieldType, typename Enable = void>
  struct DiffPrinter {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const FieldType& o, const FieldType& n);
  };
  template <typename ElementType>
  struct DiffPrinter<std::vector<ElementType>, void> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const std::vector<ElementType>& o,
                          const std::vector<ElementType>& n) {
      if (o.size() != n.size()) {
        buffer_collection.LogError(FROM_HERE, "o%s.size(): %" PRIu64 " n%s.size(): %" PRIu64,
                                   field_name.c_str(), o.size(), field_name.c_str(), n.size());
      }
      for (uint32_t i = 0; i < std::max(o.size(), n.size()); ++i) {
        std::string new_field_name = fbl::StringPrintf("%s[%u]", field_name.c_str(), i).c_str();
        const ElementType& blank = ElementType();
        const ElementType& o_element = i < o.size() ? o[i] : blank;
        const ElementType& n_element = i < n.size() ? n[i] : blank;
        DiffPrinter<ElementType>::PrintDiff(buffer_collection, new_field_name, o_element,
                                            n_element);
      }
    }
  };
  template <typename TableType>
  struct DiffPrinter<TableType, std::enable_if_t<fidl::IsTable<TableType>::value>> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const TableType& o, const TableType& n) {
      buffer_collection.LogTableDiffs<TableType>(field_name, o, n);
    }
  };
  template <>
  struct DiffPrinter<bool, void> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const bool& o, const bool& n) {
      if (o != n) {
        buffer_collection.LogError(FROM_HERE, "o%s: %d n%s: %d", field_name.c_str(), o,
                                   field_name.c_str(), n);
      }
    }
  };
  template <>
  struct DiffPrinter<uint32_t, void> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const uint32_t& o, const uint32_t& n) {
      if (o != n) {
        buffer_collection.LogError(FROM_HERE, "o%s: %u n%s: %u", field_name.c_str(), o,
                                   field_name.c_str(), n);
      }
    }
  };
  template <typename EnumType>
  struct DiffPrinter<EnumType, std::enable_if_t<sysmem::IsFidlEnum_v<EnumType>>> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const EnumType& o, const EnumType& n) {
      using UnderlyingType = sysmem::FidlUnderlyingTypeOrType_t<EnumType>;
      const UnderlyingType o_underlying = safe_cast<UnderlyingType>(o);
      const UnderlyingType n_underlying = safe_cast<UnderlyingType>(n);
      DiffPrinter<UnderlyingType>::PrintDiff(buffer_collection, field_name, o_underlying,
                                             n_underlying);
    }
  };
  template <>
  struct DiffPrinter<uint64_t, void> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const uint64_t& o, const uint64_t& n) {
      if (o != n) {
        buffer_collection.LogError(FROM_HERE, "o%s: %" PRIu64 " n%s: %" PRIu64, field_name.c_str(),
                                   o, field_name.c_str(), n);
      }
    }
  };
  template <>
  struct DiffPrinter<zx::vmo, void> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const zx::vmo& o, const zx::vmo& n) {
      // We don't expect to call the zx::vmo variant since !has_vmo(), but if we do get here,
      // complain + print the values regardless of what the values are or whether they differ.
      buffer_collection.LogError(FROM_HERE,
                                 "Why did we call zx::vmo PrintDiff? --- o%s: %u n%s: %u",
                                 field_name.c_str(), o.get(), field_name.c_str(), n.get());
    }
  };
  template <>
  struct DiffPrinter<zx::eventpair, void> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const zx::eventpair& o,
                          const zx::eventpair& n) {
      // We don't expect to call the zx::eventpair variant since !has_close_weak_asap(), but if we
      // do get here, complain + print the values regardless of what the values are or whether they
      // differ.
      buffer_collection.LogError(FROM_HERE,
                                 "Why did we call zx::eventpair PrintDiff? --- o%s: %u n%s: %u",
                                 field_name.c_str(), o.get(), field_name.c_str(), n.get());
    }
  };
  template <>
  struct DiffPrinter<fuchsia_math::SizeU, void> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const fuchsia_math::SizeU& o,
                          const fuchsia_math::SizeU& n) {
      if (o.width() != n.width() || o.height() != n.height()) {
        buffer_collection.LogError(FROM_HERE, "o%s: %u x %u n%s: %u x %u", field_name.c_str(),
                                   o.width(), o.height(), field_name.c_str(), n.width(),
                                   n.height());
      }
    }
  };
  template <>
  struct DiffPrinter<std::string, void> {
    static void PrintDiff(const LogicalBufferCollection& buffer_collection,
                          const std::string& field_name, const std::string& o,
                          const std::string& n) {
      if (o != n) {
        buffer_collection.LogError(FROM_HERE, "o%s: %s n%s: %s", field_name.c_str(), o.c_str(),
                                   field_name.c_str(), n.c_str());
      }
    }
  };

  template <typename Table>
  void LogTableDiffs(const std::string& field_name, const Table& o, const Table& n) const;

  template <>
  void LogTableDiffs<fuchsia_sysmem2::BufferMemorySettings>(
      const std::string& field_name, const fuchsia_sysmem2::BufferMemorySettings& o,
      const fuchsia_sysmem2::BufferMemorySettings& n) const {
    PRINT_DIFF(size_bytes);
    PRINT_DIFF(is_physically_contiguous);
    PRINT_DIFF(is_secure);
    PRINT_DIFF(coherency_domain);
    PRINT_DIFF(heap);
  }

  template <>
  void LogTableDiffs<fuchsia_sysmem2::ImageFormatConstraints>(
      const std::string& field_name, const fuchsia_sysmem2::ImageFormatConstraints& o,
      const fuchsia_sysmem2::ImageFormatConstraints& n) const {
    PRINT_DIFF(pixel_format);
    PRINT_DIFF(pixel_format_modifier);
    PRINT_DIFF(color_spaces);
    PRINT_DIFF(min_size);
    PRINT_DIFF(max_size);
    PRINT_DIFF(min_bytes_per_row);
    PRINT_DIFF(max_bytes_per_row);
    PRINT_DIFF(max_width_times_height);
    PRINT_DIFF(size_alignment);
    PRINT_DIFF(display_rect_alignment);
    PRINT_DIFF(required_min_size);
    PRINT_DIFF(required_max_size);
    PRINT_DIFF(bytes_per_row_divisor);
    PRINT_DIFF(start_offset_divisor);
  }

  template <>
  void LogTableDiffs<fuchsia_sysmem2::SingleBufferSettings>(
      const std::string& field_name, const fuchsia_sysmem2::SingleBufferSettings& o,
      const fuchsia_sysmem2::SingleBufferSettings& n) const {
    PRINT_DIFF(buffer_settings);
    PRINT_DIFF(image_format_constraints);
  }

  template <>
  void LogTableDiffs<fuchsia_sysmem2::VmoBuffer>(const std::string& field_name,
                                                 const fuchsia_sysmem2::VmoBuffer& o,
                                                 const fuchsia_sysmem2::VmoBuffer& n) const {
    PRINT_DIFF(vmo);
    PRINT_DIFF(vmo_usable_start);
    PRINT_DIFF(close_weak_asap);
  }

  template <>
  void LogTableDiffs<fuchsia_sysmem2::BufferCollectionInfo>(
      const std::string& field_name, const fuchsia_sysmem2::BufferCollectionInfo& o,
      const fuchsia_sysmem2::BufferCollectionInfo& n) const {
    PRINT_DIFF(settings);
    PRINT_DIFF(buffers);
  }

  template <>
  void LogTableDiffs<fuchsia_sysmem2::Heap>(const std::string& field_name,
                                            const fuchsia_sysmem2::Heap& o,
                                            const fuchsia_sysmem2::Heap& n) const {
    PRINT_DIFF(heap_type);
    PRINT_DIFF(id);
  }
#undef PRINT_DIFF

  void LogDiffsBufferCollectionInfo(const fuchsia_sysmem2::BufferCollectionInfo& o,
                                    const fuchsia_sysmem2::BufferCollectionInfo& n) const {
    LOG(WARNING, "LogDiffsBufferCollectionInfo()");
    LogTableDiffs<fuchsia_sysmem2::BufferCollectionInfo>("", o, n);
  }

  void LogConstraints(Location location, NodeProperties* node_properties,
                      const fuchsia_sysmem2::BufferCollectionConstraints& constraints) const;
  void LogBufferCollectionInfo(IndentTracker& indent_tracker,
                               const fuchsia_sysmem2::BufferCollectionInfo& bci) const;
  void LogPixelFormatAndModifier(
      IndentTracker& indent_tracker, NodeProperties* node_properties,
      const fuchsia_sysmem2::PixelFormatAndModifier& pixel_format_and_modifier) const;
  void LogImageFormatConstraints(IndentTracker& indent_tracker, NodeProperties* node_properties,
                                 const fuchsia_sysmem2::ImageFormatConstraints& ifc) const;
  void LogPrunedSubTree(NodeProperties* subtree) const;
  void LogNodeConstraints(std::vector<NodeProperties*> nodes) const;

  // subtree must remain alive >= returned filter
  fit::function<NodeFilterResult(const NodeProperties&)> PrunedSubtreeFilter(
      NodeProperties& subtree, fit::function<bool(const NodeProperties&)> visit_keep) const;

  static fbl::RefPtr<LogicalBufferCollection> CommonCreate(
      Device* parent_device, const ClientDebugInfo* client_debug_info);

  bool CommonCreateBufferCollectionTokenStage1(fbl::RefPtr<LogicalBufferCollection> self,
                                               NodeProperties* new_node_properties,
                                               const TokenServerEnd& token_request,
                                               BufferCollectionToken** out_token);

  void HandleTokenFailure(BufferCollectionToken& token, zx_status_t status);

  void IncStrongNodeTally();
  void DecStrongNodeTally();
  void CheckForZeroStrongNodes();

  void IncStrongParentVmoCount();
  void DecStrongParentVmoCount();
  void CheckForZeroStrongParentVmoCount();

  void CreateParentVmoInspect(zx_koid_t parent_vmo_koid);

  void ClearBuffers();

  bool FlattenPixelFormatAndModifiers(const fuchsia_sysmem2::BufferUsage& buffer_usage,
                                      fuchsia_sysmem2::BufferCollectionConstraints& constraints);

  Device* parent_device_ = nullptr;

  // This owns the current tree of BufferCollectionToken, BufferCollection, OrphanedNode.  The
  // Location in the tree is determined by creation path.  Child Node(s) are children because they
  // were created via their parent node.  The root node is created by CreateSharedCollection() which
  // also creates the LogicalBufferCollection.
  //
  // We use shared_ptr<> to manage NodeProperties only so that Node can have a std::weak_ptr<> back
  // to NodeProperties instead of a raw pointer, since the Node can last longer than NodeProperties,
  // despite NodeProperties being the primary non-transient owner of Node.  This way we avoid using
  // a raw pointer from Node to NodeProperties.
  //
  // The tree at root_ is the only non-transient ownership of NodeProperties.  Transient ownership
  // lasts only during a portion of a single dispatch on parent_device_->dispatcher().
  std::shared_ptr<NodeProperties> root_;

  std::vector<ConstraintInfoSnapshot> constraints_at_allocation_;

  bool is_allocate_attempted_ = false;

  // Iff true, initial allocation has been attempted and has succeeded or
  // failed.  Both allocation_result_status_ and allocation_result_info_ are
  // not meaningful until has_allocation_result_ is true.
  bool has_allocation_result_ = false;
  std::optional<fuchsia_sysmem2::BufferCollectionInfo> buffer_collection_info_before_population_;
  std::optional<fuchsia_sysmem2::Error> maybe_allocation_error_;
  std::optional<fuchsia_sysmem2::BufferCollectionInfo> allocation_result_info_;

  MemoryAllocator* memory_allocator_ = nullptr;
  std::optional<CollectionName> name_;

  // 0 means not dispensable.  Non-zero means dispensable, with each value being a group of
  // BufferCollectionToken(s) / BufferCollection(s) that were all created from a single
  // BufferCollectionToken that was created with AttachToken() or which had SetDispensable() called
  // on it.  Each group's constraints are aggregated together and succeed or fail to logically
  // allocate as a group, considered in order by when each group's constraints are ready, not in
  // order by dispensable_ordinal values.
  uint64_t next_dispensable_ordinal_ = 1;

  // Information about the current client - only valid while aggregating state for a particular
  // client.
  const NodeProperties* current_node_properties_ = nullptr;

  inspect::Node inspect_node_;
  inspect::StringProperty name_property_;
  inspect::UintProperty vmo_count_property_;
  inspect::ValueList vmo_properties_;

  // This does not actually need to be a koid, but for now we do get the value from a koid, so we
  // want the initial value at the start of the constructor to be the invalid koid value, until we
  // set this to a real koid value that's unique to "this".
  uint64_t buffer_collection_id_ = ZX_KOID_INVALID;

  // From buffers_remaining to server_end.
  std::multimap<uint32_t, zx::eventpair> lifetime_tracking_;

  // The key is buffer_index. In the success case, removing a single item from this map is performed
  // by TrackedParentVmo::do_delete. Because do_delete also runs when we want to just clear buffers_
  // in an error path, when we clear buffers_ we move it out, clear it, then delete the moved-out
  // items. This way we don't try to mutate buffers_ during buffers_.clear().
  std::unordered_map<uint32_t, std::unique_ptr<LogicalBuffer>> buffers_;

  // It's nice for members containing timers to be last for destruction order purposes, but the
  // destructor also explicitly cancels timers to avoid any brittle-ness from members potentially
  // added below creation_timer_ (so this doesn't actually need to be last).
  async::TaskMethod<LogicalBufferCollection, &LogicalBufferCollection::CreationTimedOut>
      creation_timer_{this};

  bool is_verbose_logging_ = false;

  // Only tracked while Node::is_currently_connected() true, to allow for Node sub-classes that may
  // stick around for a short duration after their channel is closed, depending on FIDL C++
  // generated code requirements on how close / disconnect works.
  std::unordered_map<zx_koid_t, NodeProperties*> node_properties_by_node_ref_keep_koid_;

  bool done_with_group_child_selection_ = false;

  // This can become true before initial allocation if waiting on secure allocators at least once
  // is/was necessary. Once this becomes true it stays true, even after this collection is no longer
  // currently waiting on secure allocators.
  //
  // This field helps avoid creation of extra child inspect nodes when the wait is over.
  bool waiting_for_secure_allocators_ready_ = false;

  uint32_t strong_node_count_ = 0;
  uint32_t strong_parent_vmo_count_ = 0;

  const zx::time create_time_monotonic_ = zx::time::infinite_past();
};

}  // namespace sysmem_driver

#endif  // SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_LOGICAL_BUFFER_COLLECTION_H_
