// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_BASE_STATUS_H_
#define MEDIA_BASE_STATUS_H_

#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include "base/location.h"
#include "base/strings/string_piece.h"
#include "base/values.h"
#include "media/base/crc_16.h"
#include "media/base/media_export.h"
#include "media/base/media_serializers_base.h"
#if defined(STARBOARD)
#include "third_party/abseil-cpp/absl/types/optional.h"
#endif  // defined(STARBOARD)

// Mojo namespaces for serialization friend declarations.
namespace mojo {
template <typename T, typename U>
struct StructTraits;
}  // namespace mojo

#define POST_STATUS_AND_RETURN_ON_FAILURE(eval_to_status, cb, ret) \
  do {                                                             \
    const auto EVALUATED = (eval_to_status);                       \
    if (!EVALUATED.is_ok()) {                                      \
      cb.Run(std::move(EVALUATED));                                \
      return ret;                                                  \
    }                                                              \
  } while (0)

namespace media {

// See media/base/status.md for details and instructions for
// using TypedStatus<T>.

// This is the type that enum classes used for specializing |TypedStatus| must
// extend from.
using StatusCodeType = uint16_t;

// This is the type that TypedStatusTraits::Group should be.
using StatusGroupType = base::StringPiece;

// This is the type that a status will get serialized into for UKM purposes.
using UKMPackedType = uint64_t;

namespace internal {

template <typename T>
struct SecondArgType {};

template <typename R, typename A1, typename A2>
struct SecondArgType<R(A1, A2)> {
  using Type = A2;
};

#if !defined(STARBOARD)
union UKMPackHelper {
  struct bits {
    uint16_t group;
    StatusCodeType code;
    uint32_t extra_data;
  } __attribute__((packed)) bits;
  UKMPackedType packed;

  static_assert(sizeof(bits) == sizeof(packed));
};
#endif  // !defined(STARBOARD)

struct MEDIA_EXPORT StatusData {
  StatusData();
  StatusData(const StatusData&);
  StatusData(StatusGroupType group,
             StatusCodeType code,
             std::string message,
             UKMPackedType root_cause);
  ~StatusData();
  StatusData& operator=(const StatusData&);

  std::unique_ptr<StatusData> copy() const;
  void AddLocation(const base::Location&);

  // Enum group ID.
  std::string group;

  // Entry within enum, cast to base type.
  StatusCodeType code;

  // The current error message (Can be used for
  // https://developer.mozilla.org/en-US/docs/Web/API/Status)
  std::string message;

  // Stack frames
  std::vector<base::Value> frames;

  // Store a root cause. Helpful for debugging, as it can end up containing
  // the chain of causes.
  std::unique_ptr<StatusData> cause;

  // Data attached to the error
  base::Value data;

  // The root-cause status, as packed for UKM.
  UKMPackedType packed_root_cause = 0;
};

#define NAME_DETECTOR(detector_name, field)                            \
  template <typename T>                                                \
  struct detector_name {                                               \
    template <typename, typename>                                      \
    struct field##is_enum {                                            \
      constexpr static bool value = false;                             \
    };                                                                 \
    template <typename V>                                              \
    struct field##is_enum<V, decltype(V::field)> {                     \
      constexpr static bool value = true;                              \
    };                                                                 \
    template <typename, typename>                                      \
    struct field##_is_member {                                         \
      constexpr static bool value = false;                             \
    };                                                                 \
    template <typename V>                                              \
    struct field##_is_member<                                          \
        V,                                                             \
        std::enable_if_t<std::is_pointer_v<decltype(&V::field)>, V>> { \
      constexpr static bool value = true;                              \
    };                                                                 \
    constexpr static bool as_enum_value = field##is_enum<T, T>::value; \
    constexpr static bool as_method = field##_is_member<T, T>::value;  \
  }

NAME_DETECTOR(HasOkCode, kOk);
NAME_DETECTOR(HasPackExtraData, PackExtraData);
NAME_DETECTOR(HasSetDefaultOk, OkEnumValue);

#undef NAME_DETECTOR

// Helper class to allow traits with no default enum.
template <typename T>
struct StatusTraitsHelper {
  static constexpr bool has_ok = HasOkCode<typename T::Codes>::as_enum_value;
  static constexpr bool has_default = HasSetDefaultOk<T>::as_method;
  static constexpr bool has_pack = HasPackExtraData<T>::as_method;

  // If T defines OkEnumValue(), then return it. Otherwise, return an
  // T::Codes::kOk if that's defined, or absl::nullopt if its not.
  static constexpr absl::optional<typename T::Codes> OkEnumValue() {
    if constexpr (has_default) {
      return T::OkEnumValue();
    } else if constexpr (has_ok) {
      return T::Codes::kOk;
    } else {
      return absl::nullopt;
    }
  }

  // If T defined PackExtraData(), then evaluate it. Otherwise, return a default
  // value. |PackExtraData| is an optional method that can operate on the
  // internal status data in order to pack it into a 32-bit entry for UKM.
  static constexpr uint32_t PackExtraData(const StatusData& info) {
    if constexpr (has_pack) {
      return T::PackExtraData(info);
    } else {
      return 0;
    }
  }
};

// Implicitly converts to an ok value for any implementation of TypedStatus.
struct OkStatusImplicitConstructionHelper {};

// For gtest, so it can print this.  Otherwise, it tries to convert to an
// integer for printing.  That'd be okay, except our implicit cast matches the
// attempt to convert to long long, and tries to get `T::kOk` for `long long`.
MEDIA_EXPORT std::ostream& operator<<(
    std::ostream& stream,
    const OkStatusImplicitConstructionHelper&);

}  // namespace internal

// Constant names for serialized TypedStatus<T>.
struct MEDIA_EXPORT StatusConstants {
  static const char kCodeKey[];
  static const char kGroupKey[];
  static const char kMsgKey[];
  static const char kStackKey[];
  static const char kDataKey[];
  static const char kCauseKey[];
  static const char kFileKey[];
  static const char kLineKey[];
};

// See media/base/status.md for details and instructions for using TypedStatus.
template <typename T>
class MEDIA_EXPORT TypedStatus {
  static_assert(std::is_enum<typename T::Codes>::value,
                "TypedStatus Traits::Codes must be an enum type.");
  static_assert(std::is_same<decltype(T::Group), StatusGroupType()>::value,
                "TypedStatus Traits::Group() must return StatusGroupType.");

  // Check that, if there is both `kOk` and a default value, that the default
  // value is `kOk`.
  constexpr static bool verify_default_okayness() {
    // Fancy new (c++17) thing: remember that 'if constexpr' short-circuits at
    // compile-time, so the later clauses don't have to be compilable if the
    // the earlier ones match.  Specifically, it's okay to reference `kOk` even
    // if `T::Codes` doesn't have `kOk`, since we check for it first.
    if constexpr (!internal::StatusTraitsHelper<T>::has_ok)
      return true;
    else if constexpr (!internal::StatusTraitsHelper<T>::has_default)
      return true;
    else
      return T::OkEnumValue() == T::Codes::kOk;
  }
  static_assert(verify_default_okayness(),
                "If kOk is defined, then either no default, or default==kOk");

 public:
  // Convenience aliases to allow, e.g., MyStatusType::Codes::kGreatDisturbance.
  using Traits = T;
  using Codes = typename T::Codes;

  // See media/base/status.md for the ways that an instantiation of TypedStatus
  // can be constructed, since there are a few.

  // Default constructor to please the Mojo Gods.
  TypedStatus() : data_(nullptr) {}

  // Copy constructor (also as a sacrifice to Lord Mojo)
  TypedStatus(const TypedStatus<T>& copy) { *this = copy; }

  // Special constructor use by OkStatus() to implicitly be cast to any required
  // status type.
  TypedStatus(const internal::OkStatusImplicitConstructionHelper&)
      : TypedStatus() {}

  // Used to implicitly create a TypedStatus from a TypedStatus::Codes value.
  TypedStatus(Codes code,
              const base::Location& location = base::Location::Current())
      : TypedStatus(code, "", location) {}

  TypedStatus(std::tuple<Codes, base::StringPiece> pack,
              const base::Location& location = base::Location::Current())
      : TypedStatus(std::get<0>(pack), std::get<1>(pack), location) {}

  // Used to allow returning {TypedStatus::Codes::kValue, CastFrom} implicitly
  // iff TypedStatus::Traits::OnCreateFrom is implemented.
  template <
      typename _T = Traits,
      typename = std::enable_if<std::is_pointer_v<decltype(&_T::OnCreateFrom)>>>
  TypedStatus(
      Codes code,
      const typename internal::SecondArgType<decltype(_T::OnCreateFrom)>::Type&
          data,
      const base::Location& location = base::Location::Current())
      : TypedStatus(code, "", location) {
    // TODO(tmathmeyer) I think we can make this dcheck a static assert.
    DCHECK(data_);
    Traits::OnCreateFrom(this, data);
  }

  // Used to allow returning {TypedStatus::Codes::kValue, "message", CastFrom}
  // implicitly iff TypedStatus::Traits::OnCreateFrom is implemented.
  template <
      typename _T = Traits,
      typename = std::enable_if<std::is_pointer_v<decltype(&_T::OnCreateFrom)>>>
  TypedStatus(
      Codes code,
      base::StringPiece message,
      const typename internal::SecondArgType<decltype(_T::OnCreateFrom)>::Type&
          data,
      const base::Location& location = base::Location::Current())
      : TypedStatus(code, message, location) {
    DCHECK(data_);
    Traits::OnCreateFrom(this, data);
  }

  // Used to allow returning {TypedStatus::Codes::kValue, cause}
  template <typename CausalStatusType>
  TypedStatus(Codes code,
              TypedStatus<CausalStatusType>&& cause,
              const base::Location& location = base::Location::Current())
      : TypedStatus(code, "", location) {
    static_assert(!std::is_same_v<CausalStatusType, Traits>);
    DCHECK(data_);
    AddCause(std::move(cause));
  }

  // Used to allow returning {TypedStatus::Codes::kValue, "message", cause}
  template <typename CausalStatusType>
  TypedStatus(Codes code,
              base::StringPiece message,
              TypedStatus<CausalStatusType>&& cause,
              const base::Location& location = base::Location::Current())
      : TypedStatus(code, message, location) {
    DCHECK(data_);
    AddCause(std::move(cause));
  }

  // Constructor to create a new TypedStatus from a numeric code & message.
  // These are immutable; if you'd like to change them, then you likely should
  // create a new TypedStatus.
  // NOTE: This should never be given a location parameter when called - It is
  // defaulted in order to grab the caller location.
  // Also used to allow returning {TypedStatus::Codes::kValue, "message"}
  // implicitly as a typed status.
  TypedStatus(Codes code,
              base::StringPiece message,
              const base::Location& location = base::Location::Current()) {
    // Note that |message| would be dropped when code is the default value,
    // so DCHECK that it is not set.
    if (code == internal::StatusTraitsHelper<Traits>::OkEnumValue()) {
      DCHECK(!!message.empty());
      return;
    }
    data_ = std::make_unique<internal::StatusData>(
        Traits::Group(), static_cast<StatusCodeType>(code),
        std::string(message), 0);
    data_->AddLocation(location);
  }

  TypedStatus<T>& operator=(const TypedStatus<T>& copy) {
    if (!copy.data_) {
      data_.reset();
      return *this;
    }
    data_ = copy.data_->copy();
    return *this;
  }

  bool is_ok() const { return !data_; }

  Codes code() const {
    if (!data_)
      return *internal::StatusTraitsHelper<Traits>::OkEnumValue();
    return static_cast<Codes>(data_->code);
  }

  const std::string group() const {
    return data_ ? data_->group : std::string(Traits::Group());
  }

  const std::string& message() const {
    DCHECK(data_);
    return data_->message;
  }

  // Adds the current location to StatusBase as it’s passed upwards.
  // This does not need to be called at every location that touches it, but
  // should be called for those locations where the path is ambiguous or
  // critical. This can be especially helpful across IPC boundaries. This will
  // fail on an OK status.
  // NOTE: This should never be given a parameter when called - It is defaulted
  // in order to grab the caller location.
  TypedStatus<T>&& AddHere(
      const base::Location& location = base::Location::Current()) && {
    DCHECK(data_);
    // We can't call MediaSerialize directly, because we can't include the
    // default serializers header, since it includes this header.
    data_->AddLocation(location);
    return std::move(*this);
  }

  // Allows us to append any datatype which can be converted to
  // an int/bool/string/base::Value. Any existing data associated with |key|
  // will be overwritten by |value|. This will fail on an OK status.
  template <typename D>
  TypedStatus<T>&& WithData(const char* key, const D& value) && {
    DCHECK(data_);
    data_->data.GetDict().Set(key, MediaSerialize(value));
    return std::move(*this);
  }

  template <typename D>
  void WithData(const char* key, const D& value) & {
    DCHECK(data_);
    data_->data.GetDict().Set(key, MediaSerialize(value));
  }

  // Add |cause| as the error that triggered this one.
  template <typename AnyTraitsType>
  TypedStatus<T>&& AddCause(TypedStatus<AnyTraitsType>&& cause) && {
    AddCause(std::move(cause));
    return std::move(*this);
  }

  // Add |cause| as the error that triggered this one.
  template <typename AnyTraitsType>
  void AddCause(TypedStatus<AnyTraitsType>&& cause) & {
    DCHECK(data_ && cause.data_);
    // The |cause| status is about to lose it's type forever. If it has no
    // causes, it might be sourced as the "root cause" status when sending to
    // UKM later, so it must be pre-emptively packed.
    if (!cause.data_->cause) {
      // If |cause| has no cause, then it shouldn't have |packed_root_cause|
      // either.
      DCHECK_EQ(cause.data_->packed_root_cause, 0lu);
      data_->packed_root_cause = cause.PackForUkm();
    } else {
      // If |cause| has a cause, it should have taken that causes's root-cause
      // when it was added as a cause. Since we're adding |cause| as our cause
      // now, we should steal |cause|'s root cause to be out root cause.
      DCHECK_NE(cause.data_->packed_root_cause, 0lu);
      data_->packed_root_cause = cause.data_->packed_root_cause;
    }
    data_->cause = std::move(cause.data_);
  }

#if !defined(STARBOARD)
  template <typename UKMBuilder>
  void ToUKM(UKMBuilder& builder) const {
    builder.SetStatus(PackForUkm());
    if (data_)
      builder.SetRootCause(data_->packed_root_cause);
  }
#endif  // !defined(STARBOARD)

  inline bool operator==(Codes code) const { return code == this->code(); }

  inline bool operator!=(Codes code) const { return code != this->code(); }

  inline bool operator==(const TypedStatus<T>& other) const {
    return other.code() == code();
  }

  inline bool operator!=(const TypedStatus<T>& other) const {
    return other.code() != code();
  }

  template <typename OtherType>
  class Or {
   private:
    template <typename X>
    struct OrTypeUnwrapper {
      using type = Or<X>;
    };
    template <typename X>
    struct OrTypeUnwrapper<Or<X>> {
      using type = Or<X>;
    };

   public:
    using ErrorType = TypedStatus;

    ~Or() = default;

    // Create an Or type implicitly from a TypedStatus
    Or(TypedStatus<T>&& error) : error_(std::move(error)) {
      // `error_` must not be ok.
      DCHECK(!error_->is_ok());
    }

    Or(const TypedStatus<T>& error) : error_(error) {
      DCHECK(!error_->is_ok());
    }

    // Create an Or type implicitly from the alternate OtherType.
    Or(OtherType&& value) : value_(std::move(value)) {}
    Or(const OtherType& value) : value_(value) {}

    // Create an Or type explicitly from a code
    Or(typename T::Codes code,
       const base::Location& location = base::Location::Current())
        : error_(TypedStatus<T>(code, "", location)) {
      DCHECK(!error_->is_ok());
    }

    // Create an Or type implicitly from any brace-initializer list that could
    // have been used to create the typed status
    template <typename First, typename... Rest>
    Or(typename T::Codes code,
       const First& first,
       const Rest&... rest,
       const base::Location& location = base::Location::Current())
        : error_(TypedStatus<T>(code, first, rest..., location)) {
      DCHECK(!error_->is_ok());
    }

    // Move- and copy- construction and assignment are okay.
    Or(const Or&) = default;
    Or(Or&&) = default;
    Or& operator=(Or&) = default;
    Or& operator=(Or&&) = default;

    bool has_value() const { return value_.has_value(); }

    inline bool operator==(typename T::Codes code) const {
      // We can't use Or<T>::code() directly, since it might not be allowed
      // due to not having an OK or default code.
      if (error_)
        return error_->code() == code;
      return internal::StatusTraitsHelper<Traits>::OkEnumValue() == code;
    }

    inline bool operator!=(typename T::Codes code) const {
      return !(*this == code);
    }

    // Return the error, if we have one.
    // Callers should ensure that this |!has_value()|.
    TypedStatus<T> error() && {
      CHECK(error_);
      auto error = std::move(*error_);
      error_.reset();
      return error;
    }

    // Return the value, if we have one.
    // Callers should ensure that this |has_value()|.
    OtherType value() && {
      CHECK(value_);
      auto value = std::move(std::get<0>(*value_));
      value_.reset();
      return value;
    }

    // Return constref of the value, if we have one.
    // Callers should ensure that this |has_value()|.
    const OtherType& operator->() const {
      CHECK(value_);
      return std::get<0>(*value_);
    }

    const OtherType& operator*() const {
      CHECK(value_);
      return std::get<0>(*value_);
    }

    typename T::Codes code() const {
      DCHECK(error_ || value_);
      using helper = internal::StatusTraitsHelper<Traits>;
      static_assert(
          helper::OkEnumValue().has_value(),
          "Cannot call Or::code() without OkEnumValue or kOk defined");
      return error_ ? error_->code() : *helper::OkEnumValue();
    }

    template <typename FnType,
              typename ReturnType =
                  decltype(std::declval<FnType>()(std::declval<OtherType>())),
              typename OrReturn = typename OrTypeUnwrapper<ReturnType>::type>
    OrReturn MapValue(FnType&& lambda) && {
      CHECK(error_ || value_);
      if (!has_value()) {
        auto error = std::move(*error_);
        error_.reset();
        return error;
      }
      CHECK(value_);
      auto value = std::move(std::get<0>(*value_));
      value_.reset();
      return lambda(std::move(value));
    }

    template <typename FnType,
              typename ReturnType =
                  decltype(std::declval<FnType>()(std::declval<OtherType>())),
              typename ConvertTo = typename ReturnType::ErrorType>
    ReturnType MapValue(
        FnType&& lambda,
        typename ConvertTo::Codes on_error,
        base::StringPiece message = "",
        base::Location location = base::Location::Current()) && {
      CHECK(error_ || value_);
      if (!has_value()) {
        auto error = std::move(*error_);
        error_.reset();
        return ConvertTo(on_error, message, location)
            .AddCause(std::move(error));
      }
      CHECK(value_);
      auto value = std::move(std::get<0>(*value_));
      value_.reset();
      return lambda(std::move(value));
    }

   private:
    absl::optional<TypedStatus<T>> error_;

    // We wrap |OtherType| in a container so that windows COM wrappers work.
    // They override operator& and similar, and won't compile in a
    // absl::optional.
    absl::optional<std::tuple<OtherType>> value_;
  };

 private:
  std::unique_ptr<internal::StatusData> data_;

  template <typename StatusEnum, typename DataView>
  friend struct mojo::StructTraits;

  // Allow media-serialization
  friend struct internal::MediaSerializer<TypedStatus<T>>;

  // Allow AddCause.
  template <typename StatusEnum>
  friend class TypedStatus;

#if !defined(STARBOARD)
  UKMPackedType PackForUkm() const {
    internal::UKMPackHelper result;
    // the group field is a crc16 hash of the constant name of the status,
    // and is not controlled by the user or browser session in any way. These
    // strings will always be something like "DecoderStatus" or "PipelineStatus"
    // and represent the name of the enum that we record in the |group| field.
    result.bits.group = crc16(Traits::Group().data());
    result.bits.code = static_cast<StatusCodeType>(code());
    result.bits.extra_data = 0;
    return result.packed;
  }
#endif  // !defined(STARBOARD)
};

template <typename T>
inline bool operator==(typename T::Codes code, const TypedStatus<T>& status) {
  return status == code;
}

template <typename T>
inline bool operator!=(typename T::Codes code, const TypedStatus<T>& status) {
  return status != code;
}

// Convenience function to return |kOk|.
// OK won't have a message, trace, or data associated with them, and DCHECK
// if they are added.
MEDIA_EXPORT internal::OkStatusImplicitConstructionHelper OkStatus();

}  // namespace media

#endif  // MEDIA_BASE_STATUS_H_
