// 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_BUFFER_COLLECTION_H_
#define SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_H_

#include <fidl/fuchsia.sysmem/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2/cpp/fidl.h>
#include <lib/fidl/internal.h>

#include <list>

#include "lib/fidl/cpp/wire/wire_messaging_declarations.h"
#include "lib/zx/channel.h"
#include "logging.h"
#include "logical_buffer_collection.h"
#include "node.h"
#include "src/devices/sysmem/drivers/sysmem/device.h"

namespace sysmem_driver {

// This class indirectly implements both V1 and V2 BufferCollection server.
//
// This class can't directly implement both servers because FIDL completers for one-way messages
// from client to server end up using the same type, which makes the overrride(s) ambiguous for any
// one-way message with no parameters.
class BufferCollection : public Node {
 public:
  using ServerEndV1 = fidl::ServerEnd<typename fuchsia_sysmem::BufferCollection>;
  using ServerEndV2 = fidl::ServerEnd<typename fuchsia_sysmem2::BufferCollection>;
  using ServerEnd = std::variant<ServerEndV1, ServerEndV2>;

  // Use EmplaceInTree() instead of Create() (until we switch to llcpp when we can have a new
  // Create() that does what EmplaceInTree() currently does).  The returned reference is valid while
  // this Node is in the tree under root_.
  static BufferCollection& EmplaceInTree(
      fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection, BufferCollectionToken* token,
      const CollectionServerEnd& server_end);
  ~BufferCollection() override;

  //
  // LogicalBufferCollection uses these:
  //

  bool is_set_constraints_seen() const { return is_set_constraints_seen_; }
  bool has_constraints();

  // has_constraints() must be true to call this.
  const fuchsia_sysmem2::BufferCollectionConstraints& constraints();

  // has_constraints() must be true to call this, and will stay true after calling this.
  fuchsia_sysmem2::BufferCollectionConstraints CloneConstraints();

  fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection_shared();

  bool should_propagate_failure_to_parent_node() const;

  // Node interface
  bool ReadyForAllocation() override;
  void OnBuffersAllocated(const AllocationResult& allocation_result) override;
  BufferCollectionToken* buffer_collection_token() override;
  const BufferCollectionToken* buffer_collection_token() const override;
  BufferCollection* buffer_collection() override;
  const BufferCollection* buffer_collection() const override;
  BufferCollectionTokenGroup* buffer_collection_token_group() override;
  const BufferCollectionTokenGroup* buffer_collection_token_group() const override;
  OrphanedNode* orphaned_node() override;
  const OrphanedNode* orphaned_node() const override;
  bool is_connected_type() const override;
  bool is_currently_connected() const override;
  const char* node_type_string() const override;
  ConnectionVersion connection_version() const override;

  void Bind(CollectionServerEnd collection_server_end);

 protected:
  void BindInternalV1(zx::channel collection_request,
                      ErrorHandlerWrapper error_handler_wrapper) override;
  void BindInternalV2(zx::channel collection_request,
                      ErrorHandlerWrapper error_handler_wrapper) override;
  void BindInternalCombinedV1AndV2(zx::channel server_end,
                                   ErrorHandlerWrapper error_handler_wrapper) override;

 private:
  friend class FidlServer;

  struct V1 : public fidl::Server<fuchsia_sysmem::BufferCollection> {
    explicit V1(BufferCollection& parent) : parent_(parent) {}

    //
    // V1:
    //
    // FIDL "compose Node" "interface" (identical among BufferCollection, BufferCollectionToken,
    // BufferCollectionTokenGroup)
    //
    void Sync(SyncCompleter::Sync& completer) override;
    void DeprecatedSync(DeprecatedSyncCompleter::Sync& completer) override;
    void Close(CloseCompleter::Sync& completer) override;
    void DeprecatedClose(DeprecatedCloseCompleter::Sync& completer) override;
    void GetNodeRef(GetNodeRefCompleter::Sync& completer) override;
    void IsAlternateFor(IsAlternateForRequest& request,
                        IsAlternateForCompleter::Sync& completer) override;
    void SetName(SetNameRequest& request, SetNameCompleter::Sync& completer) override;
    void DeprecatedSetName(DeprecatedSetNameRequest& request,
                           DeprecatedSetNameCompleter::Sync& completer) override;
    void SetDebugClientInfo(SetDebugClientInfoRequest& request,
                            SetDebugClientInfoCompleter::Sync& completer) override;
    void DeprecatedSetDebugClientInfo(
        DeprecatedSetDebugClientInfoRequest& request,
        DeprecatedSetDebugClientInfoCompleter::Sync& completer) override;
    void SetDebugTimeoutLogDeadline(SetDebugTimeoutLogDeadlineRequest& request,
                                    SetDebugTimeoutLogDeadlineCompleter::Sync& completer) override;
    void SetVerboseLogging(SetVerboseLoggingCompleter::Sync& completer) override;

    //
    // V1:
    //
    // fuchsia.sysmem.BufferCollection interface methods (see also "compose Node" methods above)
    //
    void SetConstraints(SetConstraintsRequest& request,
                        SetConstraintsCompleter::Sync& completer) override;
    void WaitForBuffersAllocated(WaitForBuffersAllocatedCompleter::Sync& completer) override;
    void CheckBuffersAllocated(CheckBuffersAllocatedCompleter::Sync& completer) override;
    void SetConstraintsAuxBuffers(SetConstraintsAuxBuffersRequest& request,
                                  SetConstraintsAuxBuffersCompleter::Sync& completer) override;
    void GetAuxBuffers(GetAuxBuffersCompleter::Sync& completer) override;
    void AttachToken(AttachTokenRequest& request, AttachTokenCompleter::Sync& completer) override;
    void AttachLifetimeTracking(AttachLifetimeTrackingRequest& request,
                                AttachLifetimeTrackingCompleter::Sync& completer) override;

    BufferCollection& parent_;
  };

  struct V2 : public fidl::Server<fuchsia_sysmem2::BufferCollection>, public fbl::Recyclable<V2> {
    explicit V2(BufferCollection& parent) : parent_(parent) {}

    //
    // FIDL "compose Node" "interface" (identical among BufferCollection, BufferCollectionToken,
    // BufferCollectionTokenGroup)
    //
    void Sync(SyncCompleter::Sync& completer) override;
    void Release(ReleaseCompleter::Sync& completer) override;
    void GetNodeRef(GetNodeRefCompleter::Sync& completer) override;
    void IsAlternateFor(IsAlternateForRequest& request,
                        IsAlternateForCompleter::Sync& completer) override;
    void GetBufferCollectionId(GetBufferCollectionIdCompleter::Sync& completer) override;
    void SetName(SetNameRequest& request, SetNameCompleter::Sync& completer) override;
    void SetDebugClientInfo(SetDebugClientInfoRequest& request,
                            SetDebugClientInfoCompleter::Sync& completer) override;
    void SetDebugTimeoutLogDeadline(SetDebugTimeoutLogDeadlineRequest& request,
                                    SetDebugTimeoutLogDeadlineCompleter::Sync& completer) override;
    void SetVerboseLogging(SetVerboseLoggingCompleter::Sync& completer) override;
    void SetWeak(SetWeakCompleter::Sync& completer) override;

    //
    // fuchsia.sysmem.BufferCollection interface methods (see also "compose Node" methods above)
    //
    void SetConstraints(SetConstraintsRequest& request,
                        SetConstraintsCompleter::Sync& completer) override;
    void WaitForAllBuffersAllocated(WaitForAllBuffersAllocatedCompleter::Sync& completer) override;
    void CheckAllBuffersAllocated(CheckAllBuffersAllocatedCompleter::Sync& completer) override;
    void AttachToken(AttachTokenRequest& request, AttachTokenCompleter::Sync& completer) override;
    void AttachLifetimeTracking(AttachLifetimeTrackingRequest& request,
                                AttachLifetimeTrackingCompleter::Sync& completer) override;
    void SetWeakOk(SetWeakOkRequest& request, SetWeakOkCompleter::Sync& completer) override;

    void handle_unknown_method(
        fidl::UnknownMethodMetadata<fuchsia_sysmem2::BufferCollection> metadata,
        fidl::UnknownMethodCompleter::Sync& completer) override;

    BufferCollection& parent_;
  };

  explicit BufferCollection(fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection,
                            const BufferCollectionToken& token,
                            const CollectionServerEnd& server_end);

  void CloseServerBinding(zx_status_t epitaph) override;

  // The rights attenuation mask driven by usage, so that read-only usage
  // doesn't get write, etc.
  uint32_t GetUsageBasedRightsAttenuation();

  uint32_t GetClientVmoRights();
  void MaybeCompleteWaitForBuffersAllocated();
  void MaybeFlushPendingLifetimeTracking();

  void FailAsync(Location location, fuchsia_sysmem2::Error error, const char* format, ...)
      __PRINTFLIKE(4, 5);
  // FailSync must be used instead of FailAsync if the current method has a completer that needs a
  // reply.
  template <typename Completer>
  void FailSync(Location location, Completer& completer, fuchsia_sysmem2::Error error,
                const char* format, ...) __PRINTFLIKE(5, 6);

  fpromise::result<fuchsia_sysmem2::BufferCollectionInfo> CloneResultForSendingV2(
      const fuchsia_sysmem2::BufferCollectionInfo& buffer_collection_info);

  fpromise::result<fuchsia_sysmem::BufferCollectionInfo2> CloneResultForSendingV1(
      const fuchsia_sysmem2::BufferCollectionInfo& buffer_collection_info);

  template <typename Completer>
  bool CommonSetConstraintsStage1(Completer& completer);

  template <typename Completer>
  bool CommonWaitForAllBuffersAllocatedStage1(bool enforce_set_constraints_before_wait,
                                              Completer& completer, trace_async_id_t* out_event_id);

  template <typename Completer>
  bool CommonCheckAllBuffersAllocatedStage1(Completer& completer,
                                            std::optional<fuchsia_sysmem2::Error>* result);

  template <typename Completer>
  bool CommonAttachTokenStage1(uint32_t rights_attenuation_mask, Completer& completer,
                               NodeProperties** out_node_properties);

  template <typename Completer>
  void CommonAttachLifetimeTracking(zx::eventpair server_end, uint32_t buffers_remaining,
                                    Completer& completer);

  std::optional<V1> v1_server_;
  std::optional<V2> v2_server_;

  // FIDL protocol enforcement.
  bool is_set_constraints_seen_ = false;

  std::list<std::pair</*async_id*/ uint64_t, V1::WaitForBuffersAllocatedCompleter::Async>>
      pending_wait_for_buffers_allocated_v1_;
  std::list<std::pair</*async_id*/ uint64_t, V2::WaitForAllBuffersAllocatedCompleter::Async>>
      pending_wait_for_buffers_allocated_v2_;
  std::optional<fidl::ServerBindingRef<fuchsia_sysmem::BufferCollection>> server_binding_v1_;
  std::optional<fidl::ServerBindingRef<fuchsia_sysmem2::BufferCollection>> server_binding_v2_;

  // Becomes set when OnBuffersAllocated() is called, and stays set after that.
  std::optional<AllocationResult> logical_allocation_result_;

  struct PendingLifetimeTracking {
    zx::eventpair server_end;
    uint32_t buffers_remaining;
  };
  std::vector<PendingLifetimeTracking> pending_lifetime_tracking_;

  bool wait_for_buffers_seen_ = false;
};

}  // namespace sysmem_driver

#endif  // SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_H_
