/*
 * 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/Portability.h>
#include <folly/futures/Try.h>
#include <functional>

namespace folly {

// forward declaration
template <class T> class Future;

template <class T>
class Promise {
public:
  Promise();
  ~Promise();

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

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

  /** Return a Future tied to the shared core state. This can be called only
    once, thereafter Future already retrieved exception will be raised. */
  Future<T> getFuture();

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

  /** Fulfill the Promise 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 Promise 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 promise with
  /// an exception (or special value) indicating how the interrupt was
  /// handled.
  void setInterruptHandler(std::function<void(exception_wrapper const&)>);

  /// Sugar to fulfill this Promise<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 Promise 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);

  bool isFulfilled();

private:
  typedef typename Future<T>::corePtr corePtr;
  template <class> friend class Future;

  // Whether the Future has been retrieved (a one-time operation).
  bool retrieved_;

  // shared core state object
  corePtr core_;

  void throwIfFulfilled();
  void throwIfRetrieved();
  void detach();
};

}

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