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

#ifndef SRC_LIB_FIDL_CPP_INCLUDE_LIB_FIDL_CPP_INTERNAL_MAKE_RESPONSE_CONTEXT_H_
#define SRC_LIB_FIDL_CPP_INCLUDE_LIB_FIDL_CPP_INTERNAL_MAKE_RESPONSE_CONTEXT_H_

#include <lib/fidl/cpp/any_error_in.h>
#include <lib/fidl/cpp/unified_messaging.h>
#include <lib/fidl/llcpp/client_base.h>

#include <optional>

namespace fidl {
namespace internal {

// |DecodeResponseAndFoldError| decodes an incoming message |incoming| returns
// a transport-specific result type (e.g. |fidl::Result| for Zircon channel
// transport). In doing so it combines any FIDL application error from the error
// syntax with transport errors.
//
// If a terminal error occurred which warrants unbinding, |out_maybe_unbind|
// will be populated with a reason if not nullptr.
template <typename FidlMethod>
auto DecodeResponseAndFoldError(::fidl::IncomingMessage&& incoming,
                                ::std::optional<::fidl::UnbindInfo>* out_maybe_unbind) {
  using ResultType = typename FidlMethod::Protocol::Transport::template Result<FidlMethod>;
  using NaturalResponse = ::fidl::Response<FidlMethod>;
  constexpr bool HasApplicationError =
      ::fidl::internal::NaturalMethodTypes<FidlMethod>::HasApplicationError;
  constexpr bool IsAbsentBody = ::fidl::internal::NaturalMethodTypes<FidlMethod>::IsAbsentBody;

  // Check error from the underlying transport.
  if (!incoming.ok()) {
    ResultType error = ::fitx::error(incoming.error());
    if (out_maybe_unbind != nullptr) {
      out_maybe_unbind->emplace(incoming.error());
    }
    return error;
  }

  ::fitx::result decoded = [&] {
    if constexpr (IsAbsentBody) {
      return DecodeTransactionalMessage(std::move(incoming));
    } else {
      using Body = typename MessageTraits<NaturalResponse>::Payload;
      return DecodeTransactionalMessage<Body>(std::move(incoming));
    }
  }();

  // Check decoding error.
  if (decoded.is_error()) {
    ResultType error = ::fitx::error(decoded.error_value());
    if (out_maybe_unbind != nullptr) {
      out_maybe_unbind->emplace(decoded.error_value());
    }
    return error;
  }

  if constexpr (IsAbsentBody) {
    // Absent body.
    ResultType value = ::fitx::success();
    return value;
  } else {
    NaturalResponse response =
        NaturalMessageConverter<NaturalResponse>::FromDomainObject(std::move(decoded.value()));
    if constexpr (HasApplicationError) {
      // Fold application error.
      if (response.is_error()) {
        ResultType error = response.take_error();
        return error;
      }
      ZX_DEBUG_ASSERT(response.is_ok());
      if constexpr (::fidl::internal::NaturalMethodTypes<FidlMethod>::IsEmptyStructPayload) {
        // Omit empty structs.
        ResultType value = ::fitx::success();
        return value;
      } else {
        ResultType value = response.take_value();
        return value;
      }
    } else {
      ResultType value = ::fitx::ok(std::move(response));
      return value;
    }
  }
}

// |MakeResponseContext| is a helper to create an adaptor from a |ResponseContext|
// to a response/result callback. It returns a raw pointer which deletes itself
// upon the receipt of a response or an error.
template <typename FidlMethod>
ResponseContext* MakeResponseContext(uint64_t ordinal,
                                     ::fidl::ClientCallback<FidlMethod> callback) {
  using ResultType = typename FidlMethod::Protocol::Transport::template Result<FidlMethod>;
  using CallbackType = ::fidl::ClientCallback<FidlMethod>;

  class ResponseContext final : public ::fidl::internal::ResponseContext {
   public:
    explicit ResponseContext(uint64_t ordinal, CallbackType&& callback)
        : ::fidl::internal::ResponseContext(ordinal), callback_(std::move(callback)) {}

   private:
    std::optional<::fidl::UnbindInfo> OnRawResult(
        ::fidl::IncomingMessage&& result,
        ::fidl::internal::IncomingTransportContext transport_context) override {
      std::optional<fidl::UnbindInfo> maybe_unbind;
      ResultType value = DecodeResponseAndFoldError<FidlMethod>(std::move(result), &maybe_unbind);
      callback_(value);
      delete this;
      return maybe_unbind;
    }

    ::fidl::ClientCallback<FidlMethod> callback_;
  };

  return new ResponseContext(ordinal, std::forward<CallbackType>(callback));
}

}  // namespace internal
}  // namespace fidl

#endif  // SRC_LIB_FIDL_CPP_INCLUDE_LIB_FIDL_CPP_INTERNAL_MAKE_RESPONSE_CONTEXT_H_
