// 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 LIB_FIDL_LLCPP_ASYNC_TRANSACTION_H_
#define LIB_FIDL_LLCPP_ASYNC_TRANSACTION_H_

#include <lib/fidl/llcpp/async_binding.h>
#include <lib/fidl/llcpp/transaction.h>
#include <lib/zx/channel.h>
#include <zircon/fidl.h>

#include <memory>
#include <utility>

namespace fidl {

namespace internal {

// An implementation of |fidl::Transaction|. Designed to work with |fidl::BindServer|, which allows
// message dispatching of multiple in-flight asynchronous transactions from a multi-threaded
// |dispatcher|. Note that |AsyncTransaction| itself assumes that only one thread at a time will act
// on it.
// The channel is owned by |AsyncBinding|, not the transaction.
class AsyncTransaction final : public Transaction {
 public:
  explicit AsyncTransaction(zx_txid_t txid, bool* binding_released)
      : txid_(txid), binding_released_(binding_released) {}

  AsyncTransaction(AsyncTransaction&& other) noexcept : Transaction(std::move(other)) {
    if (this != &other) {
      MoveImpl(std::move(other));
    }
  }

  AsyncTransaction& operator=(AsyncTransaction&& other) noexcept {
    Transaction::operator=(std::move(other));
    if (this != &other) {
      MoveImpl(std::move(other));
    }
    return *this;
  }

  virtual ~AsyncTransaction() { ZX_ASSERT(!owned_binding_); }

  zx_status_t Reply(fidl::OutgoingMessage* message) final;

  void EnableNextDispatch() final;

  void Close(zx_status_t epitaph) final;

  void InternalError(UnbindInfo error) final;

  std::unique_ptr<Transaction> TakeOwnership() final;

  bool IsUnbound() final;

 private:
  friend fidl::internal::AnyAsyncServerBinding;

  std::optional<UnbindInfo> Dispatch(std::shared_ptr<AsyncBinding>&& binding,
                                     fidl_incoming_msg_t* msg);

  void MoveImpl(AsyncTransaction&& other) noexcept {
    txid_ = other.txid_;
    other.txid_ = 0;
    owned_binding_ = std::move(other.owned_binding_);
    unowned_binding_ = std::move(other.unowned_binding_);
    binding_released_ = other.binding_released_;
    other.binding_released_ = nullptr;
  }

  zx_txid_t txid_ = 0;
  // An AsyncTransaction may only access the AsyncBinding via one of owned_binding_ or
  // unowned_binding_. On Dispatch(), the AsyncTransaction takes ownership of the internal reference
  // used by the dispatcher (keep_alive_) in owned_binding_. Calls to EnableNextDispatch(), Close(),
  // or TakeOwnership() within the scope of Dispatch() move the reference back into keep_alive_,
  // setting unowned_binding_. Otherwise, keep_alive_ is restored from owned_binding_ prior to
  // Dispatch() returning.
  std::shared_ptr<AsyncBinding> owned_binding_ = {};
  std::weak_ptr<AsyncBinding> unowned_binding_ = {};
  bool* binding_released_ = nullptr;
  std::optional<UnbindInfo> unbind_info_;
  bool* moved_ = nullptr;
};

}  // namespace internal

}  // namespace fidl

#endif  // LIB_FIDL_LLCPP_ASYNC_TRANSACTION_H_
