/*
 * Copyright 2015 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <folly/futures/Promise.h>
#include <folly/Portability.h>

namespace folly {

/*
 * SharedPromise provides the same interface as Promise, but you can extract
 * multiple Futures from it, i.e. you can call getFuture() as many times as
 * you'd like. When the SharedPromise is fulfilled, all of the Futures will be
 * called back. Calls to getFuture() after the SharedPromise is fulfilled return
 * a completed Future. If you find yourself constructing collections of Promises
 * and fulfilling them simultaneously with the same value, consider this
 * utility instead. Likewise, if you find yourself in need of setting multiple
 * callbacks on the same Future (which is indefinitely unsupported), consider
 * refactoring to use SharedPromise to "split" the Future.
 */
template <class T>
class SharedPromise {
public:
  SharedPromise() = default;
  ~SharedPromise() = default;

  // not copyable
  SharedPromise(SharedPromise const&) = delete;
  SharedPromise& operator=(SharedPromise const&) = delete;

  // movable
  SharedPromise(SharedPromise<T>&&) noexcept;
  SharedPromise& operator=(SharedPromise<T>&&) noexcept;

  /**
   * Return a Future tied to the shared core state. Unlike Promise::getFuture,
   * this can be called an unlimited number of times per SharedPromise.
   */
  Future<T> getFuture();

  /** Return the number of Futures associated with this SharedPromise */
  size_t size();

  /** Fulfill the SharedPromise with an exception_wrapper */
  void setException(exception_wrapper ew);

  /** Fulfill the SharedPromise with an exception_ptr, e.g.
    try {
      ...
    } catch (...) {
      p.setException(std::current_exception());
    }
    */
  FOLLY_DEPRECATED("use setException(exception_wrapper)")
  void setException(std::exception_ptr const&);

  /** Fulfill the SharedPromise with an exception type E, which can be passed to
    std::make_exception_ptr(). Useful for originating exceptions. If you
    caught an exception the exception_wrapper form is more appropriate.
    */
  template <class E>
  typename std::enable_if<std::is_base_of<std::exception, E>::value>::type
  setException(E const&);

  /// Set an interrupt handler to handle interrupts. See the documentation for
  /// Future::raise(). Your handler can do whatever it wants, but if you
  /// bother to set one then you probably will want to fulfill the SharedPromise with
  /// an exception (or special value) indicating how the interrupt was
  /// handled.
  void setInterruptHandler(std::function<void(exception_wrapper const&)>);

  /// Sugar to fulfill this SharedPromise<Unit>
  template <class B = T>
  typename std::enable_if<std::is_same<Unit, B>::value, void>::type
  setValue() {
    setTry(Try<T>(T()));
  }

  /** Set the value (use perfect forwarding for both move and copy) */
  template <class M>
  void setValue(M&& value);

  void setTry(Try<T>&& t);

  /** Fulfill this SharedPromise with the result of a function that takes no
    arguments and returns something implicitly convertible to T.
    Captures exceptions. e.g.

    p.setWith([] { do something that may throw; return a T; });
  */
  template <class F>
  void setWith(F&& func);

private:
  std::mutex mutex_;
  size_t size_{0};
  bool hasValue_{false};
  Try<T> try_;
  std::vector<Promise<T>> promises_;
};

}

#include <folly/futures/Future.h>
#include <folly/futures/SharedPromise-inl.h>
