/*
 * 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 <type_traits>
#include <exception>
#include <algorithm>
#include <folly/ExceptionWrapper.h>
#include <folly/Likely.h>
#include <folly/Memory.h>
#include <folly/Portability.h>
#include <folly/futures/FutureException.h>
#include <folly/futures/Unit.h>

namespace folly {

/*
 * Try<T> is a wrapper that contains either an instance of T, an exception, or
 * nothing. Its primary use case is as a representation of a Promise or Future's
 * result and so it provides a number of methods that are useful in that
 * context. Exceptions are stored as exception_wrappers so that the user can
 * minimize rethrows if so desired.
 *
 * To represent success or a captured exception, use Try<Unit>
 */
template <class T>
class Try {
  static_assert(!std::is_reference<T>::value,
                "Try may not be used with reference types");

  enum class Contains {
    VALUE,
    EXCEPTION,
    NOTHING,
  };

 public:
  /*
   * The value type for the Try
   */
  typedef T element_type;

  /*
   * Construct an empty Try
   */
  Try() : contains_(Contains::NOTHING) {}

  /*
   * Construct a Try with a value by copy
   *
   * @param v The value to copy in
   */
  explicit Try(const T& v) : contains_(Contains::VALUE), value_(v) {}

  /*
   * Construct a Try with a value by move
   *
   * @param v The value to move in
   */
  explicit Try(T&& v) : contains_(Contains::VALUE), value_(std::move(v)) {}

  /// Implicit conversion from Try<void> to Try<Unit>
  template <class T2 = T>
  /* implicit */
  Try(typename std::enable_if<std::is_same<Unit, T2>::value,
                              Try<void> const&>::type t);

  /*
   * Construct a Try with an exception_wrapper
   *
   * @param e The exception_wrapper
   */
  explicit Try(exception_wrapper e)
    : contains_(Contains::EXCEPTION),
      e_(folly::make_unique<exception_wrapper>(std::move(e))) {}

  /*
   * DEPRECATED
   * Construct a Try with an exception_pointer
   *
   * @param ep The exception_pointer. Will be rethrown.
   */
  FOLLY_DEPRECATED("use Try(exception_wrapper)")
  explicit Try(std::exception_ptr ep)
    : contains_(Contains::EXCEPTION) {
    try {
      std::rethrow_exception(ep);
    } catch (const std::exception& e) {
      e_ = folly::make_unique<exception_wrapper>(std::current_exception(), e);
    } catch (...) {
      e_ = folly::make_unique<exception_wrapper>(std::current_exception());
    }
  }

  // Move constructor
  Try(Try<T>&& t) noexcept;
  // Move assigner
  Try& operator=(Try<T>&& t) noexcept;

  // Copy constructor
  Try(const Try& t);
  // Copy assigner
  Try& operator=(const Try& t);

  ~Try();

  /*
   * Get a mutable reference to the contained value. If the Try contains an
   * exception it will be rethrown.
   *
   * @returns mutable reference to the contained value
   */
  T& value();
  /*
   * Get a const reference to the contained value. If the Try contains an
   * exception it will be rethrown.
   *
   * @returns const reference to the contained value
   */
  const T& value() const;

  /*
   * If the Try contains an exception, rethrow it. Otherwise do nothing.
   */
  void throwIfFailed() const;

  /*
   * Const dereference operator. If the Try contains an exception it will be
   * rethrown.
   *
   * @returns const reference to the contained value
   */
  const T& operator*() const { return value(); }
  /*
   * Dereference operator. If the Try contains an exception it will be rethrown.
   *
   * @returns mutable reference to the contained value
   */
  T& operator*() { return value(); }

  /*
   * Const arrow operator. If the Try contains an exception it will be
   * rethrown.
   *
   * @returns const reference to the contained value
   */
  const T* operator->() const { return &value(); }
  /*
   * Arrow operator. If the Try contains an exception it will be rethrown.
   *
   * @returns mutable reference to the contained value
   */
  T* operator->() { return &value(); }

  /*
   * @returns True if the Try contains a value, false otherwise
   */
  bool hasValue() const { return contains_ == Contains::VALUE; }
  /*
   * @returns True if the Try contains an exception, false otherwise
   */
  bool hasException() const { return contains_ == Contains::EXCEPTION; }

  /*
   * @returns True if the Try contains an exception of type Ex, false otherwise
   */
  template <class Ex>
  bool hasException() const {
    return hasException() && e_->is_compatible_with<Ex>();
  }

  exception_wrapper& exception() {
    if (UNLIKELY(!hasException())) {
      throw FutureException("exception(): Try does not contain an exception");
    }
    return *e_;
  }

  const exception_wrapper& exception() const {
    if (UNLIKELY(!hasException())) {
      throw FutureException("exception(): Try does not contain an exception");
    }
    return *e_;
  }

  /*
   * If the Try contains an exception and it is of type Ex, execute func(Ex)
   *
   * @param func a function that takes a single parameter of type const Ex&
   *
   * @returns True if the Try held an Ex and func was executed, false otherwise
   */
  template <class Ex, class F>
  bool withException(F func) const {
    if (!hasException()) {
      return false;
    }
    return e_->with_exception<Ex>(std::move(func));
  }

  template <bool isTry, typename R>
  typename std::enable_if<isTry, R>::type get() {
    return std::forward<R>(*this);
  }

  template <bool isTry, typename R>
  typename std::enable_if<!isTry, R>::type get() {
    return std::forward<R>(value());
  }

 private:
  Contains contains_;
  union {
    T value_;
    std::unique_ptr<exception_wrapper> e_;
  };
};

/*
 * Specialization of Try for void value type. Encapsulates either success or an
 * exception.
 */
template <>
class Try<void> {
 public:
  // Construct a Try holding a successful and void result
  Try() : hasValue_(true) {}

  /*
   * Construct a Try with an exception_wrapper
   *
   * @param e The exception_wrapper
   */
  explicit Try(exception_wrapper e)
    : hasValue_(false),
      e_(folly::make_unique<exception_wrapper>(std::move(e))) {}

  /*
   * DEPRECATED
   * Construct a Try with an exception_pointer
   *
   * @param ep The exception_pointer. Will be rethrown.
   */
  FOLLY_DEPRECATED("use Try(exception_wrapper)")
  explicit Try(std::exception_ptr ep) : hasValue_(false) {
    try {
      std::rethrow_exception(ep);
    } catch (const std::exception& e) {
      e_ = folly::make_unique<exception_wrapper>(std::current_exception(), e);
    } catch (...) {
      e_ = folly::make_unique<exception_wrapper>(std::current_exception());
    }
  }

  // Copy assigner
  Try& operator=(const Try<void>& t) {
    hasValue_ = t.hasValue_;
    if (t.e_) {
      e_ = folly::make_unique<exception_wrapper>(*t.e_);
    }
    return *this;
  }
  // Copy constructor
  Try(const Try<void>& t) {
    *this = t;
  }

  // If the Try contains an exception, throws it
  void value() const { throwIfFailed(); }
  // Dereference operator. If the Try contains an exception, throws it
  void operator*() const { return value(); }

  // If the Try contains an exception, throws it
  inline void throwIfFailed() const;

  // @returns False if the Try contains an exception, true otherwise
  bool hasValue() const { return hasValue_; }
  // @returns True if the Try contains an exception, false otherwise
  bool hasException() const { return !hasValue_; }

  // @returns True if the Try contains an exception of type Ex, false otherwise
  template <class Ex>
  bool hasException() const {
    return hasException() && e_->is_compatible_with<Ex>();
  }

  /*
   * @throws FutureException if the Try doesn't contain an exception
   *
   * @returns mutable reference to the exception contained by this Try
   */
  exception_wrapper& exception() {
    if (UNLIKELY(!hasException())) {
      throw FutureException("exception(): Try does not contain an exception");
    }
    return *e_;
  }

  const exception_wrapper& exception() const {
    if (UNLIKELY(!hasException())) {
      throw FutureException("exception(): Try does not contain an exception");
    }
    return *e_;
  }

  /*
   * If the Try contains an exception and it is of type Ex, execute func(Ex)
   *
   * @param func a function that takes a single parameter of type const Ex&
   *
   * @returns True if the Try held an Ex and func was executed, false otherwise
   */
  template <class Ex, class F>
  bool withException(F func) const {
    if (!hasException()) {
      return false;
    }
    return e_->with_exception<Ex>(std::move(func));
  }

  template <bool, typename R>
  R get() {
    return std::forward<R>(*this);
  }

 private:
  bool hasValue_;
  std::unique_ptr<exception_wrapper> e_{nullptr};
};

/*
 * Extracts value from try and returns it. Throws if try contained an exception.
 *
 * @param t Try to extract value from
 *
 * @returns value contained in t
 */
template <typename T>
T moveFromTry(Try<T>&& t);

/*
 * Throws if try contained an exception.
 *
 * @param t Try to move from
 */
void moveFromTry(Try<void>&& t);

/*
 * @param f a function to execute and capture the result of (value or exception)
 *
 * @returns Try holding the result of f
 */
template <typename F>
typename std::enable_if<
  !std::is_same<typename std::result_of<F()>::type, void>::value,
  Try<typename std::result_of<F()>::type>>::type
makeTryWith(F&& f);

/*
 * Specialization of makeTryWith for void return
 *
 * @param f a function to execute and capture the result of
 *
 * @returns Try<void> holding the result of f
 */
template <typename F>
typename std::enable_if<
  std::is_same<typename std::result_of<F()>::type, void>::value,
  Try<void>>::type
makeTryWith(F&& f);

} // folly

#include <folly/futures/Try-inl.h>
