// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.


#ifndef IMPALA_COMMON_STATUS_H
#define IMPALA_COMMON_STATUS_H

#include <iosfwd>
#include <string>
#include <vector>

#include "common/compiler-util.h"
#include "common/logging.h"
#include "gen-cpp/Status_types.h"  // for TStatus
#include "gen-cpp/ErrorCodes_types.h"  // for TErrorCode
#include "gen-cpp/TCLIService_types.h" // for HS2 TStatus
#include "util/error-util.h" // for ErrorMessage

#define STATUS_API_VERSION 2

namespace impala {

class StatusPB;

/// Status is used as a function return type to indicate success, failure or cancellation
/// of the function. In case of successful completion, it only occupies sizeof(void*)
/// statically allocated memory and therefore no more members should be added to this
/// class.
//
/// A Status may either be OK (represented by passing a default constructed Status
/// instance, created via Status::OK()), or it may represent an error condition. In the
/// latter case, a Status has both an error code, which belongs to the TErrorCode enum,
/// and an error string, which may be presented to clients or logged to disk.
///
/// An error Status may also have one or more optional 'detail' strings which provide
/// further context. These strings are intended for internal consumption only - and
/// therefore will not be sent to clients.
///
/// The state associated with an error Status is encapsulated in an ErrorMsg instance to
/// ensure that the size of Status is kept very small, as it is passed around on the stack
/// as a return value. See ErrorMsg for more details on how error strings are constructed.
///
/// Example Usage:
/// Status fnB(int x) {
//
///   // Status as return value
///   Status status = fnA(x);
///   if (!status.ok()) {
///     status.AddDetail("fnA(x) went wrong");
///     return status;
///   }
//
///   int r = Read(fid);
///   // Attaches an ErrorMsg with type GENERAL to the status
///   if (r == -1) return Status("String Constructor");
//
///   int x = MoreRead(x);
///   if (x == 4711) {
///     // Specific error messages with one param
///     Status s = Status(ERROR_4711_HAS_NO_BLOCKS, x);
///     // Optional detail
///     s.AddDetail("rotation-disk-broken due to weather");
///   }
///
///   return Status::OK();
/// }
class NODISCARD Status {
 public:
  typedef strings::internal::SubstituteArg ArgType;

  ALWAYS_INLINE Status(): msg_(NULL) {}

  // Return a default constructed Status instance in the OK case.
  static ALWAYS_INLINE Status OK() { return Status(); }

  // Return a MEM_LIMIT_EXCEEDED error status.
  static Status MemLimitExceeded();
  static Status MemLimitExceeded(const std::string& details);

  static const Status CANCELLED;
  static const Status DEPRECATED_RPC;

  /// Return a CANCELLED_INTERNALLY error. This should be used for "internal"
  /// cancellation messages that were not user-initiated and are not expected to be shown
  /// to the client. 'subsystem' is the name of the subsystem in which the cancellation
  /// occurred, so that we can determine where the cancellation came from.
  static Status CancelledInternal(const char* subsystem);

  /// Copy c'tor makes copy of error detail so Status can be returned by value.
  ALWAYS_INLINE Status(const Status& status) : msg_(NULL) {
    if (UNLIKELY(status.msg_ != NULL)) CopyMessageFrom(status);
  }

  /// Move constructor that moves the error message (if any) and resets 'other' to the
  /// default OK Status.
  ALWAYS_INLINE Status(Status&& other) noexcept : msg_(other.msg_) { other.msg_ = NULL; }

  /// Status using only the error code as a parameter. This can be used for error messages
  /// that don't take format parameters.
  explicit Status(TErrorCode::type code) : Status(false, code) {}

  /// These constructors are used if the caller wants to indicate a non-successful
  /// execution and supply a client-facing error message. Using TErrorCode and
  /// parameterised error messages is the preferred way of instantiating a
  /// non-successful Status instead of the std::string constructor. These constructors
  /// log the error message and a traceback, which can be expensive, so these should only
  /// be used for rare, low-frequency errors. Status::Expected() does not log a traceback
  /// and should be used for higher-frequency errors.
  Status(TErrorCode::type error, const ArgType& arg0) : Status(false, error, arg0) {}
  Status(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1)
    : Status(false, error, arg0, arg1) {}
  Status(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2)
    : Status(false, error, arg0, arg1, arg2) {}
  Status(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3)
    : Status(false, error, arg0, arg1, arg2, arg3) {}
  Status(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4)
    : Status(false, error, arg0, arg1, arg2, arg3, arg4) {}
  Status(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5)
    : Status(false, error, arg0, arg1, arg2, arg3, arg4, arg5) {}
  Status(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5,
      const ArgType& arg6)
    : Status(false, error, arg0, arg1, arg2, arg3, arg4, arg5, arg6) {}
  Status(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5,
      const ArgType& arg6, const ArgType& arg7)
    : Status(false, error, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {}
  Status(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5,
      const ArgType& arg6, const ArgType& arg7, const ArgType& arg8)
    : Status(false, error, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) {}
  Status(TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5,
      const ArgType& arg6, const ArgType& arg7, const ArgType& arg8, const ArgType& arg9)
    : Status(false, error, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {}

  /// Used when the ErrorMsg is created as an intermediate value that is either passed to
  /// the Status or to the RuntimeState.
  explicit Status(const ErrorMsg& e);

  /// This constructor creates a Status with a default error code of GENERAL and is not
  /// intended for statuses that might be client-visible.
  /// TODO: deprecate
  explicit Status(const std::string& error_msg);

  /// "Copy" c'tor from TStatus.
  /// Retains the TErrorCode value and the message
  explicit Status(const TStatus& status);

  /// "Copy" c'tor from StatusPB (a protobuf serialized version of Status object).
  /// Retains the TErrorCode value and the message
  explicit Status(const StatusPB& status);

  /// "Copy c'tor from HS2 TStatus.
  /// Retains the TErrorCode value and the message
  explicit Status(const apache::hive::service::cli::thrift::TStatus& hs2_status);

  /// The below Status::Expected() functions create a status instance that represents
  /// an expected error. They behave the same as the constructors with the same
  /// argument types, except they do not log the error message and traceback.
  static Status Expected(const ErrorMsg& e);
  static Status Expected(const std::string& error_msg);
  static Status Expected(TErrorCode::type error);
  static Status Expected(TErrorCode::type error, const ArgType& arg0);
  static Status Expected(
      TErrorCode::type error, const ArgType& arg0, const ArgType& arg1);
  static Status Expected(TErrorCode::type error, const ArgType& arg0,
      const ArgType& arg1, const ArgType& arg2);
  static Status Expected(TErrorCode::type error, const ArgType& arg0,
      const ArgType& arg1, const ArgType& arg2, const ArgType& arg3);
  static Status Expected(TErrorCode::type error, const ArgType& arg0,
      const ArgType& arg1, const ArgType& arg2, const ArgType& arg3, const ArgType& arg4);
  static Status Expected(TErrorCode::type error, const ArgType& arg0,
      const ArgType& arg1, const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
      const ArgType& arg5);
  static Status Expected(TErrorCode::type error, const ArgType& arg0,
      const ArgType& arg1, const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
      const ArgType& arg5, const ArgType& arg6);
  static Status Expected(TErrorCode::type error, const ArgType& arg0,
      const ArgType& arg1, const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
      const ArgType& arg5, const ArgType& arg6, const ArgType& arg7);
  static Status Expected(TErrorCode::type error, const ArgType& arg0,
      const ArgType& arg1, const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
      const ArgType& arg5, const ArgType& arg6, const ArgType& arg7, const ArgType& arg8);
  static Status Expected(TErrorCode::type error, const ArgType& arg0,
      const ArgType& arg1, const ArgType& arg2, const ArgType& arg3, const ArgType& arg4,
      const ArgType& arg5, const ArgType& arg6, const ArgType& arg7, const ArgType& arg8,
      const ArgType& arg9);

  /// same as copy c'tor
  ALWAYS_INLINE Status& operator=(const Status& status) {
    // Take the slow path if either Status objects have non-NULL messages (unless they
    // are aliases).
    if (UNLIKELY(msg_ != status.msg_)) CopyMessageFrom(status);
    return *this;
  }

  /// Move assignment that moves the error message (if any) and resets 'other' to the
  /// default OK Status.
  ALWAYS_INLINE Status& operator=(Status&& other) {
    if (UNLIKELY(msg_ != NULL)) FreeMessage();
    msg_ = other.msg_;
    other.msg_ = NULL;
    return *this;
  }

  ALWAYS_INLINE ~Status() {
    // The UNLIKELY and inlining here are important hints for the compiler to
    // streamline the common case of Status::OK(). Use FreeMessage() which is
    // not inlined to free the message. This avoids potential code bloat due
    // to duplicated code from the delete statement.
    if (UNLIKELY(msg_ != NULL)) FreeMessage();
  }

  /// Retains the TErrorCode value and the message
  Status& operator=(const TStatus& status);

  bool ALWAYS_INLINE ok() const { return msg_ == NULL; }

  /// Return true if this is a user-initiated or internal cancellation.
  bool IsCancelled() const {
    return msg_ != NULL && (msg_->error() == TErrorCode::CANCELLED
                               || msg_->error() == TErrorCode::CANCELLED_INTERNALLY);
  }

  bool IsMemLimitExceeded() const {
    return msg_ != NULL
        && msg_->error() == TErrorCode::MEM_LIMIT_EXCEEDED;
  }

  bool IsInternalError() const {
    return msg_ != NULL
        && msg_->error() == TErrorCode::INTERNAL_ERROR;
  }

  bool IsRecoverableError() const {
    return msg_ != NULL
        && msg_->error() == TErrorCode::RECOVERABLE_ERROR;
  }

  bool IsDiskIoError() const {
    return msg_ != NULL
        && msg_->error() == TErrorCode::DISK_IO_ERROR;
  }

  bool IsThreadPoolError() const {
    return msg_ != NULL
      && (msg_->error() == TErrorCode::THREAD_POOL_SUBMIT_FAILED ||
          msg_->error() == TErrorCode::THREAD_POOL_TASK_TIMED_OUT);
  }

  /// Returns the error message associated with a non-successful status.
  const ErrorMsg& msg() const {
    DCHECK(msg_ != NULL);
    return *msg_; // NOLINT: clang-tidy thinks this might deref a nullptr
  }

  /// Add a detail string. Calling this method is only defined on a non-OK message
  void AddDetail(const std::string& msg);

  /// Does nothing if status.ok().
  /// Otherwise: if 'this' is an error status, adds the error msg from 'status';
  /// otherwise assigns 'status'.
  void MergeStatus(const Status& status);

  /// Convert into TStatus. Call this if 'status_container' contains an optional TStatus
  /// field named 'status'. This also sets status_container->__isset.status.
  template <typename T> void SetTStatus(T* status_container) const {
    ToThrift(&status_container->status);
    status_container->__isset.status = true;
  }

  /// Convert into TStatus.
  void ToThrift(TStatus* status) const;

  /// Serialize into StatusPB
  void ToProto(StatusPB* status) const;

  /// Returns the formatted message of the error message and the individual details of the
  /// additional messages as a single string. This should only be called internally and
  /// not to report an error back to the client.
  const std::string GetDetail() const;

  TErrorCode::type code() const {
    return msg_ == NULL ? TErrorCode::OK : msg_->error();
  }

  static const char* LLVM_CLASS_NAME;
 private:
  // Status constructors that can suppress logging via 'silent' parameter
  Status(const ErrorMsg& error_msg, bool silent);
  Status(const std::string& error_msg, bool silent);
  Status(bool silent, TErrorCode::type code);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0, const ArgType& arg1);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5,
      const ArgType& arg6);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5,
      const ArgType& arg6, const ArgType& arg7);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5,
      const ArgType& arg6, const ArgType& arg7, const ArgType& arg8);
  Status(bool silent, TErrorCode::type error, const ArgType& arg0, const ArgType& arg1,
      const ArgType& arg2, const ArgType& arg3, const ArgType& arg4, const ArgType& arg5,
      const ArgType& arg6, const ArgType& arg7, const ArgType& arg8, const ArgType& arg9);

  // A non-inline function for copying status' message.
  void CopyMessageFrom(const Status& status) noexcept;

  // A non-inline function for freeing status' message.
  void FreeMessage() noexcept;

  /// A non-inline function for unwrapping a TStatus object.
  void FromThrift(const TStatus& status);

  /// A non-inline function for unwrapping a StatusPB object.
  void FromProto(const StatusPB& status);

  /// Status uses a naked pointer to ensure the size of an instance on the stack is only
  /// the sizeof(ErrorMsg*). Every Status owns its ErrorMsg instance.
  ErrorMsg* msg_;
};

/// for debugging
std::ostream& operator<<(std::ostream& os, const Status& status);

/// some generally useful macros
#define RETURN_IF_ERROR(stmt)                          \
  do {                                                 \
    const ::impala::Status& _status = (stmt);       \
    if (UNLIKELY(!_status.ok())) return _status; \
  } while (false)

#define LOG_AND_RETURN_IF_ERROR(stmt) \
  do { \
    const ::impala::Status& _status = (stmt); \
    if (UNLIKELY(!_status.ok()))  { \
      LOG(INFO) << _status.GetDetail(); \
      return _status; \
    } \
  } while (false)

#define RETURN_VOID_IF_ERROR(stmt)                     \
  do {                                                 \
    if (UNLIKELY(!(stmt).ok())) return;                \
  } while (false)

#define ABORT_IF_ERROR(stmt) \
  do { \
    const ::impala::Status& _status = (stmt); \
    if (UNLIKELY(!_status.ok())) { \
      ABORT_WITH_ERROR(_status.GetDetail()); \
    } \
  } while (false)

// Log to FATAL and abort process, generating a core dump if enabled. This should be used
// for unexpected error cases where we want a core dump.
// LOG(FATAL) will call abort().
#define ABORT_WITH_ERROR(msg) \
  do { \
    LOG(FATAL) << msg << ". Impalad exiting.\n"; \
  } while (false)

// Log to ERROR and exit process with status 1 without calling abort() or dumping core.
// This should be used for expected error cases, e.g. bad command-line arguments where
// we just want to exit cleanly without generating core dumps.
#define CLEAN_EXIT_WITH_ERROR(msg) \
  do { \
    LOG(ERROR) << msg << ". Impalad exiting.\n"; \
    google::FlushLogFiles(google::ERROR); \
    exit(1); \
  } while (false)

/// This macro can be appended to a function definition to generate a compiler warning
/// if the result is ignored.
/// TODO: when we upgrade gcc from 4.9.2, we may be able to apply this to the Status
/// type to get this automatically for all Status-returning functions.
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
}

#endif
