// Copyright 2016 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 PERIDOT_LIB_BOUND_SET_BOUND_SET_H_
#define PERIDOT_LIB_BOUND_SET_BOUND_SET_H_

#include <vector>

#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fxl/logging.h>

namespace modular {

// "Specialization" (overload) covering unique_ptr.
template <typename T>
T* GetFidlType(std::unique_ptr<T>* p) {
  return p->get();
}

// General implementation intended to cover Binding and StrongBinding.
template <typename FidlType, typename UniqueType = FidlType*>
UniqueType Identify(FidlType* binding) {
  return binding;
}

// An extensible/derivable InterfacePtrSet/(Strong)BindingSet that contains a
// collection of objects of type T that contain FidlTypes (e.g. InterfacePtr,
// Binding, or StrongBinding). Elements are automatically removed from the
// collection and destroyed when their associated Channel experiences a
// connection error. When the set is destroyed all of the Channels will be
// closed.
//
// Unlike the Fidl library InterfacePtrSet and (Strong)BindingSet, this class
// does not prevent further mutations to the underlying Fidl type. For well-
// defined behavior, the Fidl types should not be modified after being added to
// the set.
//
// Template parameters:
// * FidlType - the Fidl type governing each element of the collection, e.g.
//  InterfacePtr, Binding, or StrongBinding
// * T - the element type of the collection
// * GetFidlType - a function that extracts the FidlType from an element of the
//  collection. Defaults to the identity function, which only works if T =
//  FidlType.
// * UniqueType - a type that uniquely identifies a FidlType in the collection.
//  For InterfacePtrs, this is a pointer to the interface. For bindings, this is
//  the pointer to the binding.
// * Identify - a function that derives a UniqueType from a FidlType. Defaults
//  behave as described at UniqueType.
template <typename FidlType, typename T = FidlType,
          FidlType* GetFidlType(T*) = GetFidlType, typename UniqueType = void*,
          UniqueType Identify(FidlType*) = Identify>
class BoundSet {
 public:
  typedef typename std::vector<T>::iterator iterator;
  BoundSet() {}
  virtual ~BoundSet() {}

  // |ptr| must be bound to a channel.
  template <typename... _Args>
  T* emplace(_Args&&... __args) {
    elements_.emplace_back(std::forward<_Args>(__args)...);
    T* const c = &elements_.back();
    FidlType* const m = GetFidlType(c);
    FXL_CHECK(m->is_bound());
    UniqueType const id = Identify(m);
    // Set the connection error handler for the newly added item to be a
    // function that will erase it from the vector.
    m->set_error_handler(
        [this, id](zx_status_t status) { OnConnectionError(id); });
    return c;
  }

  UniqueType GetId(T* object) { return Identify(GetFidlType(object)); }

  // Removes the element at the given iterator. This effectively closes the pipe
  // there if open, but it does not call OnConnectionError.
  iterator erase(iterator it) { return elements_.erase(it); }
  iterator erase(UniqueType id) {
    auto it = Find(id);
    FXL_CHECK(it != elements_.end());
    return elements_.erase(it);
  }

  // Closes the Channel associated with each of the items in this set and
  // clears the set. This does not call OnConnectionError for every interface in
  // the set.
  void clear() { elements_.clear(); }
  bool empty() const { return elements_.empty(); }
  size_t size() const { return elements_.size(); }

  iterator begin() { return elements_.begin(); }
  iterator end() { return elements_.end(); }

 protected:
  virtual void OnConnectionError(UniqueType id) { erase(id); }

 private:
  iterator Find(UniqueType id) {
    return std::find_if(elements_.begin(), elements_.end(), [this, id](T& e) {
      return Identify(GetFidlType(&e)) == id;
    });
  }

  std::vector<T> elements_;
};

// Convenience alias of BoundSet to handle non-movable FIDL types, like Bindings
// (and the mythical StrongBinding).
//
// Note that the default T here must be a unique_ptr rather than the FIDL type
// itself since these FIDL types are not movable.
template <typename FidlType, typename T = std::unique_ptr<FidlType>,
          FidlType* GetFidlType(T*) = GetFidlType>
using BoundNonMovableSet = BoundSet<FidlType, T, GetFidlType, FidlType*>;

template <typename Interface,
          typename T = std::unique_ptr<fidl::InterfacePtr<Interface>>,
          fidl::InterfacePtr<Interface>* GetFidlType(T*) = GetFidlType>
using BoundPtrSet =
    BoundNonMovableSet<fidl::InterfacePtr<Interface>, T, GetFidlType>;

// Convenience alias of BoundSet to handle Binding containers.
template <typename Interface,
          typename T = std::unique_ptr<fidl::Binding<Interface>>,
          fidl::Binding<Interface>* GetFidlType(T*) = GetFidlType>
using BindingSet = BoundNonMovableSet<fidl::Binding<Interface>, T, GetFidlType>;

}  // namespace modular

#endif  // PERIDOT_LIB_BOUND_SET_BOUND_SET_H_
