// Copyright 2018 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.

#pragma once

#include <assert.h>
#include <stdint.h>
#include <atomic>
#include <ostream>
#include <sstream>
#include <string>
#include <tuple>
#include <type_traits>

namespace overnet {

// Status codes, chosen to be compatible with gRPC & Abseil
enum class StatusCode : uint8_t {
  /// Not an error; returned on success.
  OK = 0,

  /// The operation was cancelled (typically by the caller).
  CANCELLED = 1,

  /// Unknown error. An example of where this error may be returned is if a
  /// Status value received from another address space belongs to an error-space
  /// that is not known in this address space. Also errors raised by APIs that
  /// do not return enough error information may be converted to this error.
  UNKNOWN = 2,

  /// Client specified an invalid argument. Note that this differs from
  /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
  /// problematic regardless of the state of the system (e.g., a malformed file
  /// name).
  INVALID_ARGUMENT = 3,

  /// Deadline expired before operation could complete. For operations that
  /// change the state of the system, this error may be returned even if the
  /// operation has completed successfully. For example, a successful response
  /// from a server could have been delayed long enough for the deadline to
  /// expire.
  DEADLINE_EXCEEDED = 4,

  /// Some requested entity (e.g., file or directory) was not found.
  NOT_FOUND = 5,

  /// Some entity that we attempted to create (e.g., file or directory) already
  /// exists.
  ALREADY_EXISTS = 6,

  /// The caller does not have permission to execute the specified operation.
  /// PERMISSION_DENIED must not be used for rejections caused by exhausting
  /// some resource (use RESOURCE_EXHAUSTED instead for those errors).
  /// PERMISSION_DENIED must not be used if the caller can not be identified
  /// (use UNAUTHENTICATED instead for those errors).
  PERMISSION_DENIED = 7,

  /// The request does not have valid authentication credentials for the
  /// operation.
  UNAUTHENTICATED = 16,

  /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
  /// entire file system is out of space.
  RESOURCE_EXHAUSTED = 8,

  /// Operation was rejected because the system is not in a state required for
  /// the operation's execution. For example, directory to be deleted may be
  /// non-empty, an rmdir operation is applied to a non-directory, etc.
  ///
  /// A litmus test that may help a service implementor in deciding
  /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
  ///  (a) Use UNAVAILABLE if the client can retry just the failing call.
  ///  (b) Use ABORTED if the client should retry at a higher-level
  ///      (e.g., restarting a read-modify-write sequence).
  ///  (c) Use FAILED_PRECONDITION if the client should not retry until
  ///      the system state has been explicitly fixed. E.g., if an "rmdir"
  ///      fails because the directory is non-empty, FAILED_PRECONDITION
  ///      should be returned since the client should not retry unless
  ///      they have first fixed up the directory by deleting files from it.
  ///  (d) Use FAILED_PRECONDITION if the client performs conditional
  ///      REST Get/Update/Delete on a resource and the resource on the
  ///      server does not match the condition. E.g., conflicting
  ///      read-modify-write on the same resource.
  FAILED_PRECONDITION = 9,

  /// The operation was aborted, typically due to a concurrency issue like
  /// sequencer check failures, transaction aborts, etc.
  ///
  /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
  /// and UNAVAILABLE.
  ABORTED = 10,

  /// Operation was attempted past the valid range. E.g., seeking or reading
  /// past end of file.
  ///
  /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
  /// if the system state changes. For example, a 32-bit file system will
  /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
  /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
  /// an offset past the current file size.
  ///
  /// There is a fair bit of overlap between FAILED_PRECONDITION and
  /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
  /// when it applies so that callers who are iterating through a space can
  /// easily look for an OUT_OF_RANGE error to detect when they are done.
  OUT_OF_RANGE = 11,

  /// Operation is not implemented or not supported/enabled in this service.
  UNIMPLEMENTED = 12,

  /// Internal errors. Means some invariants expected by underlying System has
  /// been broken. If you see one of these errors, Something is very broken.
  INTERNAL = 13,

  /// The service is currently unavailable. This is a most likely a transient
  /// condition and may be corrected by retrying with a backoff.
  ///
  /// \warning Although data MIGHT not have been transmitted when this
  /// status occurs, there is NOT A GUARANTEE that the server has not seen
  /// anything. So in general it is unsafe to retry on this status code
  /// if the call is non-idempotent.
  ///
  /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
  /// and UNAVAILABLE.
  UNAVAILABLE = 14,

  /// Unrecoverable data loss or corruption.
  DATA_LOSS = 15,
};

const char* StatusCodeString(StatusCode s);

namespace status_impl {

struct StatusPayload final {
  std::atomic<uint32_t> refs;
  std::string reason;
};

struct StatusRep final {
  std::atomic<uint32_t> refs;
  StatusCode code;
  std::string reason;
};

extern const std::string empty_string;

}  // namespace status_impl

template <class T>
class StatusOr;

// A result from some operation.
// Currently a status code and a string reason, although this may be extended in
// the future to also capture additional data in the case of errors.
// Contains an optimization whereby Status objects containing no reason string
// are carried without allocation.
class [[nodiscard]] Status final {
 public:
  Status(StatusCode code) : code_(static_cast<uintptr_t>(code)) {}
  Status(StatusCode code, std::string reason)
      : rep_(new status_impl::StatusRep{{1}, code, std::move(reason)}) {}
  ~Status() {
    static_assert(sizeof(Status) == sizeof(void*),
                  "sizeof(Status) should be one pointer");
    if (is_code_only())
      return;
    if (rep_->refs.fetch_add(-1, std::memory_order_acq_rel) == 1)
      delete rep_;
  }

  Status(Status && other) : code_(other.code_) { other.code_ = 0; }
  Status(const Status& other) : code_(other.code_) {
    if (!is_code_only()) {
      rep_->refs.fetch_add(1, std::memory_order_relaxed);
    }
  }
  Status& operator=(const Status& other) {
    Status copy(other);
    Swap(&copy);
    return *this;
  }
  Status& operator=(Status&& other) {
    Swap(&other);
    return *this;
  }

  void Swap(Status * other) { std::swap(code_, other->code_); }

  static const Status& Ok() { return Static<>::Ok; }
  static const Status& Cancelled() { return Static<>::Cancelled; }
  static const Status& Unavailable() { return Static<>::Unavailable; }

  const Status& OrCancelled() const {
    if (is_ok())
      return Cancelled();
    return *this;
  }

  StatusCode code() const {
    return is_code_only() ? static_cast<StatusCode>(code_) : rep_->code;
  }
  bool is_ok() const { return code() == StatusCode::OK; }
  bool is_error() const { return !is_ok(); }
  const std::string& reason() const {
    return is_code_only() ? status_impl::empty_string : rep_->reason;
  }

  Status WithContext(const char* context) const {
    if (is_ok())
      return *this;
    return Status(code(), std::string(context) + ": " + reason());
  }

  template <class F>
  Status WithLazyContext(F generator) const {
    if (is_ok())
      return *this;
    std::ostringstream msg;
    msg << generator() << ": " << reason();
    return Status(code(), msg.str());
  }

  template <class T>
  StatusOr<typename std::remove_reference<T>::type> Or(T && value) const;

  template <class F>
  auto Then(F fn)->decltype(fn()) {
    if (is_error())
      return *this;
    return fn();
  }

  void Ignore() {}
  void MustSucceed() const {
    if (is_error()) {
      abort();
    }
  }

  static Status FromZx(int32_t zx_status);
  static Status FromZx(int32_t zx_status, const char* desc);

 private:
  bool is_code_only() const { return code_ < 256; }

  template <int I = 0>
  struct Static {
    static const Status Ok;
    static const Status Cancelled;
    static const Status Unavailable;
  };

  union {
    status_impl::StatusRep* rep_;
    uintptr_t code_;
  };
};

template <int I>
const Status Status::Static<I>::Ok{StatusCode::OK};
template <int I>
const Status Status::Static<I>::Cancelled{StatusCode::CANCELLED};
template <int I>
const Status Status::Static<I>::Unavailable{StatusCode::UNAVAILABLE};

inline std::ostream& operator<<(std::ostream& out, const Status& status) {
  out << StatusCodeString(status.code());
  if (status.reason().length()) {
    out << "(" << status.reason() << ")";
  }
  return out;
}

// Either a status or a T - allows carrying a separate object in the case of
// success.
template <class T>
class [[nodiscard]] StatusOr final {
 public:
  using element_type = T;

  template <typename U, typename = typename std::enable_if<
                            !std::is_convertible<U, Status>::value &&
                            !std::is_convertible<U, StatusOr>::value>::type>
  StatusOr(U && value)
      : code_(StatusCode::OK), storage_(std::forward<U>(value)) {}
  StatusOr(StatusCode code, const std::string& description)
      : code_(code),
        storage_(new status_impl::StatusPayload{{1}, description}) {
    if (code_ == StatusCode::OK)
      abort();
  }
  // Raise an untyped (but non-ok) Status object to a StatusOr
  StatusOr(const Status& status) : StatusOr(status.code(), status.reason()) {}
  StatusOr(const StatusOr& other) : code_(other.code_) {
    if (is_ok()) {
      new (&storage_) Storage(*other.unwrap());
    } else {
      auto* p = other.unwrap_err();
      new (&storage_) Storage(p);
      p->refs.fetch_add(1, std::memory_order_relaxed);
    }
  }
  StatusOr(StatusOr && other) : code_(other.code_) {
    if (is_ok()) {
      new (&storage_) Storage(std::move(*other.unwrap()));
    } else {
      // TODO(ctiller): consider a payload-less variant of StatusOr failures so
      // we can omit the fetch_add here
      auto* p = other.unwrap_err();
      new (&storage_) Storage(p);
      p->refs.fetch_add(1, std::memory_order_relaxed);
    }
  }
  StatusOr& operator=(const StatusOr& other) {
    if (&other == this)
      return *this;
    this->~StatusOr();
    new (this) StatusOr(other);
    return *this;
  }
  ~StatusOr() {
    if (is_ok()) {
      unwrap()->~T();
    } else {
      auto* p = unwrap_err();
      if (p->refs.fetch_add(-1, std::memory_order_acq_rel) == 1)
        delete p;
    }
  }

  void Ignore() {}

  StatusCode code() const { return code_; }
  bool is_ok() const { return code() == StatusCode::OK; }
  bool is_error() const { return !is_ok(); }
  const std::string& reason() const {
    return is_ok() ? status_impl::empty_string : unwrap_err()->reason;
  }

  // Return (a pointer-to) an object on successful completion, or nullptr on
  // failure
  const T* get() const {
    if (is_ok())
      return unwrap();
    return nullptr;
  }

  T* get() {
    if (is_ok())
      return unwrap();
    return nullptr;
  }

  const T& value() const { return *unwrap(); }

  const T* operator->() const { return unwrap(); }
  T* operator->() { return unwrap(); }
  const T& operator*() const { return *unwrap(); }
  T& operator*() { return *unwrap(); }

  // Lower to an untyped status object
  Status AsStatus() const {
    if (reason().empty())
      return Status(code());
    return Status(code(), reason());
  }

  template <class F>
  auto Then(F fn) const->decltype(fn(*get())) {
    if (is_error())
      return AsStatus();
    return fn(*get());
  }

  template <class F>
  auto Then(F fn)->decltype(fn(std::move(*get()))) {
    if (is_error())
      return AsStatus();
    return fn(std::move(*get()));
  }

 private:
  const T* unwrap() const {
    assert(is_ok());
    return &storage_.ok;
  }

  T* unwrap() {
    assert(is_ok());
    return &storage_.ok;
  }

  status_impl::StatusPayload* unwrap_err() const {
    assert(is_error());
    return storage_.payload;
  }

  StatusCode code_;
  union Storage {
    Storage() {}
    ~Storage() {}
    template <class U>
    Storage(U&& v) : ok(std::forward<U>(v)) {}
    Storage(status_impl::StatusPayload* p) : payload(p) {}
    T ok;
    status_impl::StatusPayload* payload;
  };
  Storage storage_;
};

template <class T>
StatusOr<typename std::remove_reference<T>::type> Status::Or(T&& t) const {
  if (is_error()) {
    return *this;
  } else {
    return std::forward<T>(t);
  }
}

template <class T>
inline std::ostream& operator<<(std::ostream& out, const StatusOr<T>& status) {
  out << StatusCodeString(status.code());
  if (status.reason().length()) {
    out << "(" << status.reason() << ")";
  }
  if (status.is_ok()) {
    out << ":" << status.value();
  }
  return out;
}

}  // namespace overnet
