//===-------- Error.h - Enforced error checking for ORC RT ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef ORC_RT_ERROR_H
#define ORC_RT_ERROR_H

#include "compiler.h"
#include "extensible_rtti.h"
#include "stl_extras.h"

#include <cassert>
#include <memory>
#include <string>
#include <type_traits>

namespace __orc_rt {

/// Base class for all errors.
class ErrorInfoBase : public RTTIExtends<ErrorInfoBase, RTTIRoot> {
public:
  virtual std::string toString() const = 0;
};

/// Represents an environmental error.
class ORC_RT_NODISCARD Error {

  template <typename ErrT, typename... ArgTs>
  friend Error make_error(ArgTs &&...Args);

  friend Error repackage_error(std::unique_ptr<ErrorInfoBase>);

  template <typename ErrT> friend std::unique_ptr<ErrT> error_cast(Error &);

  template <typename T> friend class Expected;

public:
  /// Destroy this error. Aborts if error was not checked, or was checked but
  /// not handled.
  ~Error() { assertIsChecked(); }

  Error(const Error &) = delete;
  Error &operator=(const Error &) = delete;

  /// Move-construct an error. The newly constructed error is considered
  /// unchecked, even if the source error had been checked. The original error
  /// becomes a checked success value.
  Error(Error &&Other) {
    setChecked(true);
    *this = std::move(Other);
  }

  /// Move-assign an error value. The current error must represent success, you
  /// you cannot overwrite an unhandled error. The current error is then
  /// considered unchecked. The source error becomes a checked success value,
  /// regardless of its original state.
  Error &operator=(Error &&Other) {
    // Don't allow overwriting of unchecked values.
    assertIsChecked();
    setPtr(Other.getPtr());

    // This Error is unchecked, even if the source error was checked.
    setChecked(false);

    // Null out Other's payload and set its checked bit.
    Other.setPtr(nullptr);
    Other.setChecked(true);

    return *this;
  }

  /// Create a success value.
  static Error success() { return Error(); }

  /// Error values convert to true for failure values, false otherwise.
  explicit operator bool() {
    setChecked(getPtr() == nullptr);
    return getPtr() != nullptr;
  }

  /// Return true if this Error contains a failure value of the given type.
  template <typename ErrT> bool isA() const {
    return getPtr() && getPtr()->isA<ErrT>();
  }

private:
  Error() = default;

  Error(std::unique_ptr<ErrorInfoBase> ErrInfo) {
    auto RawErrPtr = reinterpret_cast<uintptr_t>(ErrInfo.release());
    assert((RawErrPtr & 0x1) == 0 && "ErrorInfo is insufficiently aligned");
    ErrPtr = RawErrPtr | 0x1;
  }

  void assertIsChecked() {
    if (ORC_RT_UNLIKELY(!isChecked() || getPtr())) {
      fprintf(stderr, "Error must be checked prior to destruction.\n");
      abort(); // Some sort of JIT program abort?
    }
  }

  template <typename ErrT = ErrorInfoBase> ErrT *getPtr() const {
    return reinterpret_cast<ErrT *>(ErrPtr & ~uintptr_t(1));
  }

  void setPtr(ErrorInfoBase *Ptr) {
    ErrPtr = (reinterpret_cast<uintptr_t>(Ptr) & ~uintptr_t(1)) | (ErrPtr & 1);
  }

  bool isChecked() const { return ErrPtr & 0x1; }

  void setChecked(bool Checked) { ErrPtr = (ErrPtr & ~uintptr_t(1)) | Checked; }

  template <typename ErrT = ErrorInfoBase> std::unique_ptr<ErrT> takePayload() {
    static_assert(std::is_base_of<ErrorInfoBase, ErrT>::value,
                  "ErrT is not an ErrorInfoBase subclass");
    std::unique_ptr<ErrT> Tmp(getPtr<ErrT>());
    setPtr(nullptr);
    setChecked(true);
    return Tmp;
  }

  uintptr_t ErrPtr = 0;
};

/// Construct an error of ErrT with the given arguments.
template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&...Args) {
  static_assert(std::is_base_of<ErrorInfoBase, ErrT>::value,
                "ErrT is not an ErrorInfoBase subclass");
  return Error(std::make_unique<ErrT>(std::forward<ArgTs>(Args)...));
}

/// Construct an error of ErrT using a std::unique_ptr<ErrorInfoBase>. The
/// primary use-case for this is 're-packaging' errors after inspecting them
/// using error_cast, hence the name.
inline Error repackage_error(std::unique_ptr<ErrorInfoBase> EIB) {
  return Error(std::move(EIB));
}

/// If the argument is an error of type ErrT then this function unpacks it
/// and returns a std::unique_ptr<ErrT>. Otherwise returns a nullptr and
/// leaves the error untouched. Common usage looks like:
///
/// \code{.cpp}
///   if (Error E = foo()) {
///     if (auto EV1 = error_cast<ErrorType1>(E)) {
///       // use unwrapped EV1 value.
///     } else if (EV2 = error_cast<ErrorType2>(E)) {
///       // use unwrapped EV2 value.
///     } ...
///   }
/// \endcode
template <typename ErrT> std::unique_ptr<ErrT> error_cast(Error &Err) {
  static_assert(std::is_base_of<ErrorInfoBase, ErrT>::value,
                "ErrT is not an ErrorInfoBase subclass");
  if (Err.isA<ErrT>())
    return Err.takePayload<ErrT>();
  return nullptr;
}

/// Helper for Errors used as out-parameters.
/// Sets the 'checked' flag on construction, resets it on destruction.
class ErrorAsOutParameter {
public:
  ErrorAsOutParameter(Error *Err) : Err(Err) {
    // Raise the checked bit if Err is success.
    if (Err)
      (void)!!*Err;
  }

  ~ErrorAsOutParameter() {
    // Clear the checked bit.
    if (Err && !*Err)
      *Err = Error::success();
  }

private:
  Error *Err;
};

template <typename T> class ORC_RT_NODISCARD Expected {

  template <class OtherT> friend class Expected;

  static constexpr bool IsRef = std::is_reference<T>::value;
  using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
  using error_type = std::unique_ptr<ErrorInfoBase>;
  using storage_type = std::conditional_t<IsRef, wrap, T>;
  using value_type = T;

  using reference = std::remove_reference_t<T> &;
  using const_reference = const std::remove_reference_t<T> &;
  using pointer = std::remove_reference_t<T> *;
  using const_pointer = const std::remove_reference_t<T> *;

public:
  /// Create an Expected from a failure value.
  Expected(Error Err) : HasError(true), Unchecked(true) {
    assert(Err && "Cannot create Expected<T> from Error success value");
    new (getErrorStorage()) error_type(Err.takePayload());
  }

  /// Create an Expected from a T value.
  template <typename OtherT>
  Expected(OtherT &&Val,
           std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr)
      : HasError(false), Unchecked(true) {
    new (getStorage()) storage_type(std::forward<OtherT>(Val));
  }

  /// Move-construct an Expected<T> from an Expected<OtherT>.
  Expected(Expected &&Other) { moveConstruct(std::move(Other)); }

  /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
  /// must be convertible to T.
  template <class OtherT>
  Expected(
      Expected<OtherT> &&Other,
      std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr) {
    moveConstruct(std::move(Other));
  }

  /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
  /// isn't convertible to T.
  template <class OtherT>
  explicit Expected(
      Expected<OtherT> &&Other,
      std::enable_if_t<!std::is_convertible<OtherT, T>::value> * = nullptr) {
    moveConstruct(std::move(Other));
  }

  /// Move-assign from another Expected<T>.
  Expected &operator=(Expected &&Other) {
    moveAssign(std::move(Other));
    return *this;
  }

  /// Destroy an Expected<T>.
  ~Expected() {
    assertIsChecked();
    if (!HasError)
      getStorage()->~storage_type();
    else
      getErrorStorage()->~error_type();
  }

  /// Returns true if this Expected value is in a success state (holding a T),
  /// and false if this Expected value is in a failure state.
  explicit operator bool() {
    Unchecked = HasError;
    return !HasError;
  }

  /// Returns true if this Expected value holds an Error of type error_type.
  template <typename ErrT> bool isFailureOfType() const {
    return HasError && (*getErrorStorage())->template isFailureOfType<ErrT>();
  }

  /// Take ownership of the stored error.
  ///
  /// If this Expected value is in a success state (holding a T) then this
  /// method is a no-op and returns Error::success.
  ///
  /// If thsi Expected value is in a failure state (holding an Error) then this
  /// method returns the contained error and leaves this Expected in an
  /// 'empty' state from which it may be safely destructed but not otherwise
  /// accessed.
  Error takeError() {
    Unchecked = false;
    return HasError ? Error(std::move(*getErrorStorage())) : Error::success();
  }

  /// Returns a pointer to the stored T value.
  pointer operator->() {
    assertIsChecked();
    return toPointer(getStorage());
  }

  /// Returns a pointer to the stored T value.
  const_pointer operator->() const {
    assertIsChecked();
    return toPointer(getStorage());
  }

  /// Returns a reference to the stored T value.
  reference operator*() {
    assertIsChecked();
    return *getStorage();
  }

  /// Returns a reference to the stored T value.
  const_reference operator*() const {
    assertIsChecked();
    return *getStorage();
  }

private:
  template <class T1>
  static bool compareThisIfSameType(const T1 &a, const T1 &b) {
    return &a == &b;
  }

  template <class T1, class T2>
  static bool compareThisIfSameType(const T1 &a, const T2 &b) {
    return false;
  }

  template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) {
    HasError = Other.HasError;
    Unchecked = true;
    Other.Unchecked = false;

    if (!HasError)
      new (getStorage()) storage_type(std::move(*Other.getStorage()));
    else
      new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage()));
  }

  template <class OtherT> void moveAssign(Expected<OtherT> &&Other) {
    assertIsChecked();

    if (compareThisIfSameType(*this, Other))
      return;

    this->~Expected();
    new (this) Expected(std::move(Other));
  }

  pointer toPointer(pointer Val) { return Val; }

  const_pointer toPointer(const_pointer Val) const { return Val; }

  pointer toPointer(wrap *Val) { return &Val->get(); }

  const_pointer toPointer(const wrap *Val) const { return &Val->get(); }

  storage_type *getStorage() {
    assert(!HasError && "Cannot get value when an error exists!");
    return reinterpret_cast<storage_type *>(&TStorage);
  }

  const storage_type *getStorage() const {
    assert(!HasError && "Cannot get value when an error exists!");
    return reinterpret_cast<const storage_type *>(&TStorage);
  }

  error_type *getErrorStorage() {
    assert(HasError && "Cannot get error when a value exists!");
    return reinterpret_cast<error_type *>(&ErrorStorage);
  }

  const error_type *getErrorStorage() const {
    assert(HasError && "Cannot get error when a value exists!");
    return reinterpret_cast<const error_type *>(&ErrorStorage);
  }

  void assertIsChecked() {
    if (ORC_RT_UNLIKELY(Unchecked)) {
      fprintf(stderr,
              "Expected<T> must be checked before access or destruction.\n");
      abort();
    }
  }

  union {
    std::aligned_union_t<1, storage_type> TStorage;
    std::aligned_union_t<1, error_type> ErrorStorage;
  };

  bool HasError : 1;
  bool Unchecked : 1;
};

/// Consume an error without doing anything.
inline void consumeError(Error Err) {
  if (Err)
    (void)error_cast<ErrorInfoBase>(Err);
}

/// Consumes success values. It is a programmatic error to call this function
/// on a failure value.
inline void cantFail(Error Err) {
  assert(!Err && "cantFail called on failure value");
  consumeError(std::move(Err));
}

/// Auto-unwrap an Expected<T> value in the success state. It is a programmatic
/// error to call this function on a failure value.
template <typename T> T cantFail(Expected<T> E) {
  assert(E && "cantFail called on failure value");
  consumeError(E.takeError());
  return std::move(*E);
}

/// Auto-unwrap an Expected<T> value in the success state. It is a programmatic
/// error to call this function on a failure value.
template <typename T> T &cantFail(Expected<T &> E) {
  assert(E && "cantFail called on failure value");
  consumeError(E.takeError());
  return *E;
}

/// Convert the given error to a string. The error value is consumed in the
/// process.
inline std::string toString(Error Err) {
  if (auto EIB = error_cast<ErrorInfoBase>(Err))
    return EIB->toString();
  return {};
}

class StringError : public RTTIExtends<StringError, ErrorInfoBase> {
public:
  StringError(std::string ErrMsg) : ErrMsg(std::move(ErrMsg)) {}
  std::string toString() const override { return ErrMsg; }

private:
  std::string ErrMsg;
};

} // end namespace __orc_rt

#endif // ORC_RT_ERROR_H
