//
//
// Copyright 2015 gRPC authors.
//
// Licensed 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.
//
//

/// A ClientContext allows the person implementing a service client to:
///
/// - Add custom metadata key-value pairs that will propagated to the server
/// side.
/// - Control call settings such as compression and authentication.
/// - Initial and trailing metadata coming from the server.
/// - Get performance metrics (ie, census).
///
/// Context settings are only relevant to the call they are invoked with, that
/// is to say, they aren't sticky. Some of these settings, such as the
/// compression options, can be made persistent at channel construction time
/// (see \a grpc::CreateCustomChannel).
///
/// \warning ClientContext instances should \em not be reused across rpcs.

#ifndef GRPCPP_CLIENT_CONTEXT_H
#define GRPCPP_CLIENT_CONTEXT_H

#include <map>
#include <memory>
#include <string>

#include "absl/log/absl_check.h"

#include <grpc/impl/compression_types.h>
#include <grpc/impl/propagation_bits.h>
#include <grpc/support/log.h>
#include <grpcpp/impl/create_auth_context.h>
#include <grpcpp/impl/metadata_map.h>
#include <grpcpp/impl/rpc_method.h>
#include <grpcpp/impl/sync.h>
#include <grpcpp/security/auth_context.h>
#include <grpcpp/support/client_interceptor.h>
#include <grpcpp/support/config.h>
#include <grpcpp/support/slice.h>
#include <grpcpp/support/status.h>
#include <grpcpp/support/string_ref.h>
#include <grpcpp/support/time.h>

struct census_context;
struct grpc_call;

namespace grpc {
class ServerContext;
class ServerContextBase;
class CallbackServerContext;

namespace internal {
template <class InputMessage, class OutputMessage>
class CallbackUnaryCallImpl;
template <class Request, class Response>
class ClientCallbackReaderWriterImpl;
template <class Response>
class ClientCallbackReaderImpl;
template <class Request>
class ClientCallbackWriterImpl;
class ClientCallbackUnaryImpl;
class ClientContextAccessor;
class ClientAsyncResponseReaderHelper;
}  // namespace internal

template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ClientAsyncReader;
template <class W>
class ClientAsyncWriter;
template <class W, class R>
class ClientAsyncReaderWriter;
template <class R>
class ClientAsyncResponseReader;

namespace testing {
class InteropClientContextInspector;
class ClientContextTestPeer;
}  // namespace testing

namespace internal {
class RpcMethod;
template <class InputMessage, class OutputMessage>
class BlockingUnaryCallImpl;
class CallOpClientRecvStatus;
class CallOpRecvInitialMetadata;
class ServerContextImpl;
template <class InputMessage, class OutputMessage>
class CallbackUnaryCallImpl;
template <class Request, class Response>
class ClientCallbackReaderWriterImpl;
template <class Response>
class ClientCallbackReaderImpl;
template <class Request>
class ClientCallbackWriterImpl;
class ClientCallbackUnaryImpl;
class ClientContextAccessor;
}  // namespace internal

class CallCredentials;
class Channel;
class ChannelInterface;
class CompletionQueue;

/// Options for \a ClientContext::FromServerContext specifying which traits from
/// the \a ServerContext to propagate (copy) from it into a new \a
/// ClientContext.
///
/// \see ClientContext::FromServerContext
class PropagationOptions {
 public:
  PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {}

  PropagationOptions& enable_deadline_propagation() {
    propagate_ |= GRPC_PROPAGATE_DEADLINE;
    return *this;
  }

  PropagationOptions& disable_deadline_propagation() {
    propagate_ &= ~GRPC_PROPAGATE_DEADLINE;
    return *this;
  }

  PropagationOptions& enable_census_stats_propagation() {
    propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
    return *this;
  }

  PropagationOptions& disable_census_stats_propagation() {
    propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
    return *this;
  }

  PropagationOptions& enable_census_tracing_propagation() {
    propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
    return *this;
  }

  PropagationOptions& disable_census_tracing_propagation() {
    propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
    return *this;
  }

  PropagationOptions& enable_cancellation_propagation() {
    propagate_ |= GRPC_PROPAGATE_CANCELLATION;
    return *this;
  }

  PropagationOptions& disable_cancellation_propagation() {
    propagate_ &= ~GRPC_PROPAGATE_CANCELLATION;
    return *this;
  }

  uint32_t c_bitmask() const { return propagate_; }

 private:
  uint32_t propagate_;
};

/// A ClientContext allows the person implementing a service client to:
///
/// - Add custom metadata key-value pairs that will propagated to the server
///   side.
/// - Control call settings such as compression and authentication.
/// - Initial and trailing metadata coming from the server.
/// - Get performance metrics (ie, census).
///
/// Context settings are only relevant to the call they are invoked with, that
/// is to say, they aren't sticky. Some of these settings, such as the
/// compression options, can be made persistent at channel construction time
/// (see \a grpc::CreateCustomChannel).
///
/// \warning ClientContext instances should \em not be reused across rpcs.
/// \warning The ClientContext instance used for creating an rpc must remain
///          alive and valid for the lifetime of the rpc.
class ClientContext {
 public:
  ClientContext();
  ~ClientContext();

  /// Create a new \a ClientContext as a child of an incoming server call,
  /// according to \a options (\see PropagationOptions).
  ///
  /// \param server_context The source server context to use as the basis for
  /// constructing the client context.
  /// \param options The options controlling what to copy from the \a
  /// server_context.
  ///
  /// \return A newly constructed \a ClientContext instance based on \a
  /// server_context, with traits propagated (copied) according to \a options.
  static std::unique_ptr<ClientContext> FromServerContext(
      const grpc::ServerContextBase& server_context,
      PropagationOptions options = PropagationOptions());
  static std::unique_ptr<ClientContext> FromCallbackServerContext(
      const grpc::CallbackServerContext& server_context,
      PropagationOptions options = PropagationOptions());

  /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with
  /// a client call. These are made available at the server side by the \a
  /// grpc::ServerContext::client_metadata() method.
  ///
  /// \warning This method should only be called before invoking the rpc.
  ///
  /// \param meta_key The metadata key. If \a meta_value is binary data, it must
  /// end in "-bin".
  /// \param meta_value The metadata value. If its value is binary, the key name
  /// must end in "-bin".
  ///
  /// Metadata must conform to the following format:
  ///
  ///\verbatim
  /// Custom-Metadata -> Binary-Header / ASCII-Header
  /// Binary-Header -> {Header-Name "-bin" } {binary value}
  /// ASCII-Header -> Header-Name ASCII-Value
  /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - .
  /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII
  /// Custom-Metadata -> Binary-Header / ASCII-Header
  ///\endverbatim
  ///
  void AddMetadata(const std::string& meta_key, const std::string& meta_value);

  /// Return a collection of initial metadata key-value pairs. Note that keys
  /// may happen more than once (ie, a \a std::multimap is returned).
  ///
  /// \warning This method should only be called after initial metadata has been
  /// received. For streaming calls, see \a
  /// ClientReaderInterface::WaitForInitialMetadata().
  ///
  /// \return A multimap of initial metadata key-value pairs from the server.
  const std::multimap<grpc::string_ref, grpc::string_ref>&
  GetServerInitialMetadata() const {
    ABSL_CHECK(initial_metadata_received_);
    return *recv_initial_metadata_.map();
  }

  /// Return a collection of trailing metadata key-value pairs. Note that keys
  /// may happen more than once (ie, a \a std::multimap is returned).
  ///
  /// \warning This method is only callable once the stream has finished.
  ///
  /// \return A multimap of metadata trailing key-value pairs from the server.
  const std::multimap<grpc::string_ref, grpc::string_ref>&
  GetServerTrailingMetadata() const {
    // TODO(yangg) check finished
    return *trailing_metadata_.map();
  }

  /// Set the deadline for the client call.
  ///
  /// \warning This method should only be called before invoking the rpc.
  ///
  /// \param deadline the deadline for the client call. Units are determined by
  /// the type used. The deadline is an absolute (not relative) time.
  template <typename T>
  void set_deadline(const T& deadline) {
    grpc::TimePoint<T> deadline_tp(deadline);
    deadline_ = deadline_tp.raw_time();
  }

  /// Trigger wait-for-ready or not on this request.
  /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md.
  /// If set, if an RPC is made when a channel's connectivity state is
  /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast",
  /// and the channel will wait until the channel is READY before making the
  /// call.
  void set_wait_for_ready(bool wait_for_ready) {
    wait_for_ready_ = wait_for_ready;
    wait_for_ready_explicitly_set_ = true;
  }

  /// DEPRECATED: Use set_wait_for_ready() instead.
  void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); }

  /// Return the deadline for the client call.
  std::chrono::system_clock::time_point deadline() const {
    return grpc::Timespec2Timepoint(deadline_);
  }

  /// Return a \a gpr_timespec representation of the client call's deadline.
  gpr_timespec raw_deadline() const { return deadline_; }

  /// Set the per call authority header (see
  /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3).
  void set_authority(const std::string& authority) { authority_ = authority; }

  /// Return the authentication context for the associated client call.
  /// It is only valid to call this during the lifetime of the client call.
  ///
  /// \see grpc::AuthContext.
  std::shared_ptr<const grpc::AuthContext> auth_context() const {
    if (auth_context_ == nullptr) {
      auth_context_ = grpc::CreateAuthContext(call_);
    }
    return auth_context_;
  }

  /// Set credentials for the client call.
  ///
  /// A credentials object encapsulates all the state needed by a client to
  /// authenticate with a server and make various assertions, e.g., about the
  /// client’s identity, role, or whether it is authorized to make a particular
  /// call.
  ///
  /// It is legal to call this only before initial metadata is sent.
  ///
  /// \see  https://grpc.io/docs/guides/auth.html
  void set_credentials(const std::shared_ptr<grpc::CallCredentials>& creds);

  /// EXPERIMENTAL debugging API
  ///
  /// Returns the credentials for the client call. This should be used only in
  /// tests and for diagnostic purposes, and should not be used by application
  /// logic.
  std::shared_ptr<grpc::CallCredentials> credentials() { return creds_; }

  /// Return the compression algorithm the client call will request be used.
  /// Note that the gRPC runtime may decide to ignore this request, for example,
  /// due to resource constraints.
  grpc_compression_algorithm compression_algorithm() const {
    return compression_algorithm_;
  }

  /// Set \a algorithm to be the compression algorithm used for the client call.
  ///
  /// \param algorithm The compression algorithm used for the client call.
  void set_compression_algorithm(grpc_compression_algorithm algorithm);

  /// Flag whether the initial metadata should be \a corked
  ///
  /// If \a corked is true, then the initial metadata will be coalesced with the
  /// write of first message in the stream. As a result, any tag set for the
  /// initial metadata operation (starting a client-streaming or bidi-streaming
  /// RPC) will not actually be sent to the completion queue or delivered
  /// via Next.
  ///
  /// \param corked The flag indicating whether the initial metadata is to be
  /// corked or not.
  void set_initial_metadata_corked(bool corked) {
    initial_metadata_corked_ = corked;
  }

  /// Return the peer uri in a string.
  /// It is only valid to call this during the lifetime of the client call.
  ///
  /// \warning This value is never authenticated or subject to any security
  /// related code. It must not be used for any authentication related
  /// functionality. Instead, use auth_context.
  ///
  /// \return The call's peer URI.
  std::string peer() const;

  /// Sets the census context.
  /// It is only valid to call this before the client call is created. A common
  /// place of setting census context is from within the DefaultConstructor
  /// method of GlobalCallbacks.
  void set_census_context(struct census_context* ccp) { census_context_ = ccp; }

  /// Returns the census context that has been set, or nullptr if not set.
  struct census_context* census_context() const { return census_context_; }

  /// Send a best-effort out-of-band cancel on the call associated with
  /// this client context.  The call could be in any stage; e.g., if it is
  /// already finished, it may still return success.
  ///
  /// There is no guarantee the call will be cancelled.
  ///
  /// Note that TryCancel() does not change any of the tags that are pending
  /// on the completion queue. All pending tags will still be delivered
  /// (though their ok result may reflect the effect of cancellation).
  ///
  /// This method is thread-safe, and can be called multiple times from any
  /// thread.
  void TryCancel();

  /// Global Callbacks
  ///
  /// Can be set exactly once per application to install hooks whenever
  /// a client context is constructed and destructed.
  class GlobalCallbacks {
   public:
    virtual ~GlobalCallbacks() {}
    virtual void DefaultConstructor(ClientContext* context) = 0;
    virtual void Destructor(ClientContext* context) = 0;
  };
  static void SetGlobalCallbacks(GlobalCallbacks* callbacks);

  /// Should be used for framework-level extensions only.
  /// Applications never need to call this method.
  grpc_call* c_call() { return call_; }

  /// EXPERIMENTAL debugging API
  ///
  /// if status is not ok() for an RPC, this will return a detailed string
  /// of the gRPC Core error that led to the failure. It should not be relied
  /// upon for anything other than gaining more debug data in failure cases.
  std::string debug_error_string() const { return debug_error_string_; }

 private:
  // Disallow copy and assign.
  ClientContext(const ClientContext&);
  ClientContext& operator=(const ClientContext&);

  friend class grpc::testing::InteropClientContextInspector;
  friend class grpc::testing::ClientContextTestPeer;
  friend class grpc::internal::CallOpClientRecvStatus;
  friend class grpc::internal::CallOpRecvInitialMetadata;
  friend class grpc::Channel;
  template <class R>
  friend class grpc::ClientReader;
  template <class W>
  friend class grpc::ClientWriter;
  template <class W, class R>
  friend class grpc::ClientReaderWriter;
  template <class R>
  friend class grpc::ClientAsyncReader;
  template <class W>
  friend class grpc::ClientAsyncWriter;
  template <class W, class R>
  friend class grpc::ClientAsyncReaderWriter;
  template <class R>
  friend class grpc::ClientAsyncResponseReader;
  friend class grpc::internal::ClientAsyncResponseReaderHelper;
  template <class InputMessage, class OutputMessage>
  friend class grpc::internal::BlockingUnaryCallImpl;
  template <class InputMessage, class OutputMessage>
  friend class grpc::internal::CallbackUnaryCallImpl;
  template <class Request, class Response>
  friend class grpc::internal::ClientCallbackReaderWriterImpl;
  template <class Response>
  friend class grpc::internal::ClientCallbackReaderImpl;
  template <class Request>
  friend class grpc::internal::ClientCallbackWriterImpl;
  friend class grpc::internal::ClientCallbackUnaryImpl;
  friend class grpc::internal::ClientContextAccessor;

  // Used by friend class CallOpClientRecvStatus
  void set_debug_error_string(const std::string& debug_error_string) {
    debug_error_string_ = debug_error_string;
  }

  grpc_call* call() const { return call_; }
  void set_call(grpc_call* call, const std::shared_ptr<grpc::Channel>& channel);

  grpc::experimental::ClientRpcInfo* set_client_rpc_info(
      const char* method, const char* suffix_for_stats,
      grpc::internal::RpcMethod::RpcType type, grpc::ChannelInterface* channel,
      const std::vector<std::unique_ptr<
          grpc::experimental::ClientInterceptorFactoryInterface>>& creators,
      size_t interceptor_pos) {
    rpc_info_ = grpc::experimental::ClientRpcInfo(this, type, method,
                                                  suffix_for_stats, channel);
    rpc_info_.RegisterInterceptors(creators, interceptor_pos);
    return &rpc_info_;
  }

  uint32_t initial_metadata_flags() const {
    return (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) |
           (wait_for_ready_explicitly_set_
                ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET
                : 0);
  }

  std::string authority() { return authority_; }

  void SendCancelToInterceptors();

  static std::unique_ptr<ClientContext> FromInternalServerContext(
      const grpc::ServerContextBase& server_context,
      PropagationOptions options);

  bool initial_metadata_received_;
  bool wait_for_ready_;
  bool wait_for_ready_explicitly_set_;
  std::shared_ptr<grpc::Channel> channel_;
  grpc::internal::Mutex mu_;
  grpc_call* call_;
  bool call_canceled_;
  gpr_timespec deadline_;
  grpc::string authority_;
  std::shared_ptr<grpc::CallCredentials> creds_;
  mutable std::shared_ptr<const grpc::AuthContext> auth_context_;
  struct census_context* census_context_;
  std::multimap<std::string, std::string> send_initial_metadata_;
  mutable grpc::internal::MetadataMap recv_initial_metadata_;
  mutable grpc::internal::MetadataMap trailing_metadata_;

  grpc_call* propagate_from_call_;
  PropagationOptions propagation_options_;

  grpc_compression_algorithm compression_algorithm_;
  bool initial_metadata_corked_;

  std::string debug_error_string_;

  grpc::experimental::ClientRpcInfo rpc_info_;
};

}  // namespace grpc

#endif  // GRPCPP_CLIENT_CONTEXT_H
