// 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_TOKEN_H_
#define SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_TOKEN_H_

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

#include "lib/zx/channel.h"
#include "logging.h"
#include "logical_buffer_collection.h"
#include "node.h"

namespace sysmem_driver {

class BufferCollectionToken;

class BufferCollectionToken : public Node, public LoggingMixin {
 public:
  ~BufferCollectionToken() override;

  // The returned reference is owned by new_node_properties, which in turn is owned by
  // logical_buffer_collection->root_.
  static BufferCollectionToken& EmplaceInTree(
      fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection,
      NodeProperties* new_node_properties, const TokenServerEnd& server_end);

  template <class CompleterSync>
  void TokenReleaseImpl(ConnectionVersion version, CompleterSync& completer) {
    // BufferCollectionToken has one additional error case we want to check, so check before calling
    // Node::CloseImpl().
    if (buffer_collection_request_) {
      FailSync(FROM_HERE, version, completer, ZX_ERR_BAD_STATE,
               "BufferCollectionToken::Close()/Release() when buffer_collection_request_");
      // We're failing async - no need to try to fail sync.
      return;
    }
    ReleaseImpl(version, completer);
  }

  void OnServerKoid();

  void SetDispensableInternal();

  bool is_done();

  void SetBufferCollectionRequest(CollectionServerEnd buffer_collection_request);

  std::optional<CollectionServerEnd> TakeBufferCollectionRequest();

  void CloseServerBinding(zx_status_t epitaph) override;

  // 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(TokenServerEnd server_end);

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

 private:
  friend class FidlServer;

  // We keep the protocol impl separate to clarify which methods are protocol impl.  Sysmem serves
  // CombinedBufferCollectionToken which is both a V1 and V2 token at the same time.  This allows
  // us to keep the V1 and V2 protocols separate from a client's point of view, while also avoiding
  // any pointless token version conversions.  This happens to make sense for BufferCollectionToken
  // V1 and V2 since the token is logically the same in all stateful aspects; this approach being
  // used here is not an implicit proposal / promise to use this same approach for any hypothetical
  // V3.
  struct CombinedTokenServer
      : public fidl::Server<fuchsia_sysmem2_internal::CombinedBufferCollectionToken> {
    explicit CombinedTokenServer(BufferCollectionToken& parent) : parent_(parent) {}

    // V1
    //
    // FIDL "compose Node" "interface" (identical among BufferCollection, BufferCollectionToken,
    // BufferCollectionTokenGroup)
    void SyncV1(SyncV1Completer::Sync& completer) override;
    void DeprecatedSyncV1(DeprecatedSyncV1Completer::Sync& completer) override;
    void CloseV1(CloseV1Completer::Sync& completer) override;
    void DeprecatedCloseV1(DeprecatedCloseV1Completer::Sync& completer) override;
    void GetNodeRefV1(GetNodeRefV1Completer::Sync& completer) override;
    void IsAlternateForV1(IsAlternateForV1Request& request,
                          IsAlternateForV1Completer::Sync& completer) override;
    void SetNameV1(SetNameV1Request& request, SetNameV1Completer::Sync& completer) override;
    void DeprecatedSetNameV1(DeprecatedSetNameV1Request& request,
                             DeprecatedSetNameV1Completer::Sync& completer) override;
    void SetDebugClientInfoV1(SetDebugClientInfoV1Request& request,
                              SetDebugClientInfoV1Completer::Sync& completer) override;
    void DeprecatedSetDebugClientInfoV1(
        DeprecatedSetDebugClientInfoV1Request& request,
        DeprecatedSetDebugClientInfoV1Completer::Sync& completer) override;
    void SetDebugTimeoutLogDeadlineV1(
        SetDebugTimeoutLogDeadlineV1Request& request,
        SetDebugTimeoutLogDeadlineV1Completer::Sync& completer) override;
    void DeprecatedSetDebugTimeoutLogDeadlineV1(
        DeprecatedSetDebugTimeoutLogDeadlineV1Request& request,
        DeprecatedSetDebugTimeoutLogDeadlineV1Completer::Sync& completer) override;
    void SetVerboseLoggingV1(SetVerboseLoggingV1Completer::Sync& completer) override;
    // fuchsia.sysmem.BufferCollectionToken interface methods (see also "compose Node" methods
    // above)
    void DuplicateSyncV1(DuplicateSyncV1Request& request,
                         DuplicateSyncV1Completer::Sync& completer) override;
    void DuplicateV1(DuplicateV1Request& request, DuplicateV1Completer::Sync& completer) override;
    void CreateBufferCollectionTokenGroupV1(
        CreateBufferCollectionTokenGroupV1Request& request,
        CreateBufferCollectionTokenGroupV1Completer::Sync& completer) override;
    void SetDispensableV1(SetDispensableV1Completer::Sync& completer) override;

    // V2
    //
    // FIDL "compose Node" "interface" (identical among BufferCollection, BufferCollectionToken,
    // BufferCollectionTokenGroup)
    void SyncV2(SyncV2Completer::Sync& completer) override;
    void ReleaseV2(ReleaseV2Completer::Sync& completer) override;
    void GetNodeRefV2(GetNodeRefV2Completer::Sync& completer) override;
    void IsAlternateForV2(IsAlternateForV2Request& request,
                          IsAlternateForV2Completer::Sync& completer) override;
    void GetBufferCollectionIdV2(GetBufferCollectionIdV2Completer::Sync& completer) override;
    void SetWeakV2(SetWeakV2Completer::Sync& completer) override;
    void SetWeakOkV2(SetWeakOkV2Request& request, SetWeakOkV2Completer::Sync& completer) override;
    void SetNameV2(SetNameV2Request& request, SetNameV2Completer::Sync& completer) override;
    void SetDebugClientInfoV2(SetDebugClientInfoV2Request& request,
                              SetDebugClientInfoV2Completer::Sync& completer) override;
    void SetDebugTimeoutLogDeadlineV2(
        SetDebugTimeoutLogDeadlineV2Request& request,
        SetDebugTimeoutLogDeadlineV2Completer::Sync& completer) override;
    void SetVerboseLoggingV2(SetVerboseLoggingV2Completer::Sync& completer) override;
    // fuchsia.sysmem.BufferCollectionToken interface methods (see also "compose Node" methods
    // above)
    void DuplicateSyncV2(DuplicateSyncV2Request& request,
                         DuplicateSyncV2Completer::Sync& completer) override;
    void DuplicateV2(DuplicateV2Request& request, DuplicateV2Completer::Sync& completer) override;
    void CreateBufferCollectionTokenGroupV2(
        CreateBufferCollectionTokenGroupV2Request& request,
        CreateBufferCollectionTokenGroupV2Completer::Sync& completer) override;
    void SetDispensableV2(SetDispensableV2Completer::Sync& completer) override;

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

    BufferCollectionToken& parent_;
  };

  BufferCollectionToken(fbl::RefPtr<LogicalBufferCollection> parent,
                        NodeProperties* new_node_properties, const TokenServerEnd& server_end);

  void FailAsync(Location location, zx_status_t status, const char* format, ...);

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

  template <typename Completer>
  bool CommonCreateBufferCollectionTokenGroupStage1(ConnectionVersion version, Completer& completer,
                                                    NodeProperties** out_node_properties);

  std::optional<CombinedTokenServer> server_;

  std::optional<zx_status_t> async_failure_result_;

  std::optional<fidl::ServerBindingRef<fuchsia_sysmem2_internal::CombinedBufferCollectionToken>>
      server_binding_;
  ConnectionVersion last_seen_version_ = ConnectionVersion::kNoConnection;

  // This is set up to once during
  // LogicalBufferCollection::BindSharedCollection(), and essentially curries
  // the buffer_collection_request past the processing of any remaining
  // inbound messages on the BufferCollectionToken before starting to serve
  // the BufferCollection that the token was exchanged for.  This way, inbound
  // Duplicate() messages in the BufferCollectionToken are seen before any
  // BufferCollection::SetConstraints() (which might otherwise try to allocate
  // buffers too soon before all tokens are gone)

  std::optional<CollectionServerEnd> buffer_collection_request_;

  inspect::Node inspect_node_;
  inspect::UintProperty debug_id_property_;
  inspect::StringProperty debug_name_property_;
  inspect::ValueList properties_;
};

}  // namespace sysmem_driver

#endif  // SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_TOKEN_H_
