// 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_CONNECTIVITY_BLUETOOTH_LIB_FIDL_HANGING_GETTER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_LIB_FIDL_HANGING_GETTER_H_

#include <lib/fidl/cpp/clone.h>
#include <lib/fit/function.h>
#include <zircon/assert.h>

#include <optional>
#include <queue>

namespace bt_lib_fidl {

// HangingGetter generalizes the consumer/producer pattern often involved in FIDL hanging get
// implementations.
//
// USAGE:
//
// Use `Set()` to update the state watched by the FIDL method:
//
//   HangingGetter<int> foo;
//   ...
//   void OnFooUpdated(int new_foo) {
//     foo.Set(new_foo);
//   }
//
// Use `Watch()` to invoke the response callback with any updates to the state or defer it until the
// update happens later:
//
//   void GetFoo(GetFooCallback callback) {
//     foo.Watch(std::move(callback));
//   }
//
// A specialization is provided for state that is a growing collection of state updates:
//
//   HangingVectorGetter<int> foo;
//   ...
//   void OnFooUpdated(int new_foo) {
//     foo.Add(new_foo);
//   }

template <typename T, typename C = void(T)>
class HangingGetterBase {
 public:
  using Callback = fit::callback<C>;
  using Mutator = fit::function<T(T)>;

  // Returns true if a callback is already assigned to this getter.
  bool armed() const { return !callbacks_.empty(); }

  // Assign |value| to the stored state and notify any pending Watch callbacks.
  void Set(T value) {
    value_.emplace(std::move(value));
    WatchInternal();
  }

  // Mutably access the stored state via function |f| and notify any pending Watch callbacks. The
  // Mutator function |f| will receive the current value and should the return the new value after
  // applying any transformations to it.
  //
  // This is useful for value types that accumulate data. To directly assign a value, use the
  // non-mutator overload instead.
  void Transform(Mutator f) {
    ZX_DEBUG_ASSERT(f);

    // Initialize the value if it's not dirty so that the mutator can work with it.
    if (!value_) {
      value_.emplace();
    }

    value_.emplace(f(std::move(value_.value())));
    WatchInternal();
  }

  // Invoke |callback| with any updates to the state. If the state has been accessed via one of the
  // Set() functions since the last call to Watch(), then |callback| will run immediately.
  // Otherwise, |callback| is run next time the state is accessed.
  //
  // Once |callback| runs, the store state becomes cleared. The next call to one of the Set()
  // functions will default-construct a new state.
  //
  // Multiple callbacks can be queued to be notified simultaneously next time the state gets
  // updated. All callbacks will get invoked with a separate copy of the new state, however there is
  // no requirement that the state type T itself be copiable. How the value is passed to the
  // callbacks is left up to the Notify() member function implementation.
  void Watch(Callback callback) {
    callbacks_.push(std::move(callback));
    WatchInternal();
  }

 protected:
  // This member function is called when a value update triggers a registered watcher Callback to be
  // notified. This is abstract to allow HangingGetter variants to apply any necessary
  // transformations between the stored value type "T" and the parameter type of the callback type
  // "C".
  //
  // For example, this is useful when the stored type is a custom accumulator type. A
  // HangingGetterBase implementation can, for example, implement a custom mapping from the stored
  // accumulator to a FIDL struct type that the callback expects.
  virtual void Notify(std::queue<Callback> callbacks, T value) = 0;

 private:
  void WatchInternal() {
    if (!callbacks_.empty() && value_) {
      auto q = std::move(callbacks_);
      auto v = std::move(*value_);
      value_.reset();

      Notify(std::move(q), std::move(v));
    }
  }

  std::optional<T> value_;
  std::queue<Callback> callbacks_;
};

// HangingGetter type where the stored type is identical to the callback parameter type. T must be
// clonable by fidl::Clone().
template <typename T>
class HangingGetter : public HangingGetterBase<T> {
 protected:
  void Notify(std::queue<typename HangingGetter<T>::Callback> callbacks, T value) override {
    while (!callbacks.empty()) {
      auto f = std::move(callbacks.front());
      callbacks.pop();
      f(fidl::Clone(value));
    }
  }
};

template <typename T>
class HangingVectorGetter : public HangingGetter<std::vector<T>> {
 public:
  // Insert |value| to the vector and notify any pending Watch callbacks.
  void Add(T&& value) {
    this->Transform([&](auto current) {
      current.push_back(std::forward<T>(value));
      return current;
    });
  }
};

}  // namespace bt_lib_fidl

#endif  // SRC_CONNECTIVITY_BLUETOOTH_LIB_FIDL_HANGING_GETTER_H_
