// 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 KUDU_RPC_RPC_CONTEXT_H
#define KUDU_RPC_RPC_CONTEXT_H

#include <memory>
#include <stddef.h>
#include <string>

#include <glog/logging.h>

#include "kudu/gutil/gscoped_ptr.h"
#include "kudu/gutil/ref_counted.h"
#include "kudu/rpc/rpc_header.pb.h"
#include "kudu/util/monotime.h"
#include "kudu/util/status.h"

namespace google {
namespace protobuf {
class Message;
} // namespace protobuf
} // namespace google

namespace kudu {

class Slice;
class Sockaddr;
class Trace;

namespace rpc {

class InboundCall;
class RemoteUser;
class ResultTracker;
class RpcSidecar;

#define PANIC_RPC(rpc_context, message) \
  do { \
    if (rpc_context) {                              \
      rpc_context->Panic(__FILE__, __LINE__, (message));  \
    } else { \
      LOG(FATAL) << message; \
    } \
  } while (0)

// The context provided to a generated ServiceIf. This provides
// methods to respond to the RPC. In the future, this will also
// include methods to access information about the caller: e.g
// authentication info, tracing info, and cancellation status.
//
// This is the server-side analogue to the RpcController class.
class RpcContext {
 public:
  // Create an RpcContext. This is called only from generated code
  // and is not a public API.
  RpcContext(InboundCall *call,
             const google::protobuf::Message *request_pb,
             google::protobuf::Message *response_pb,
             scoped_refptr<ResultTracker> result_tracker);

  ~RpcContext();

  // Return the trace buffer for this call.
  Trace* trace();

  // Send a response to the call. The service may call this method
  // before or after returning from the original handler method,
  // and it may call this method from a different thread.
  //
  // The response should be prepared already in the response PB pointer
  // which was passed to the handler method.
  //
  // After this method returns, this RpcContext object is destroyed. The request
  // and response protobufs are also destroyed.
  void RespondSuccess();

  // Like the above, but doesn't store the results of the service call, if results
  // are being tracked.
  // Used in cases where a call specific error was set on the response protobuf,
  // the call should be considered failed, thus results shouldn't be cached.
  void RespondNoCache();

  // Respond with an error to the client. This sends back an error with the code
  // ERROR_APPLICATION. Because there is no more specific error code passed back
  // to the client, most applications should create a custom error PB extension
  // and use RespondApplicationError(...) below. This method should only be used
  // for unexpected errors where the server doesn't expect the client to do any
  // more advanced handling.
  //
  // After this method returns, this RpcContext object is destroyed. The request
  // and response protobufs are also destroyed.
  void RespondFailure(const Status &status);

  // Respond with an RPC-level error. This typically manifests to the client as
  // a remote error, one whose handling is agnostic to the particulars of the
  // sent RPC. For example, both ERROR_SERVER_TOO_BUSY and ERROR_UNAVAILABLE
  // usually cause the client to retry the RPC at a later time.
  //
  // After this method returns, this RpcContext object is destroyed. The request
  // and response protobufs are also destroyed.
  void RespondRpcFailure(ErrorStatusPB_RpcErrorCodePB err, const Status& status);

  // Respond with an application-level error. This causes the caller to get a
  // RemoteError status with the provided string message. Additionally, a
  // service-specific error extension is passed back to the client. The
  // extension must be registered with the ErrorStatusPB protobuf. For
  // example:
  //
  //   message MyServiceError {
  //     extend kudu.rpc.ErrorStatusPB {
  //       optional MyServiceError my_service_error_ext = 101;
  //     }
  //     // Add any extra fields or status codes you want to pass back to
  //     // the client here.
  //     required string extra_error_data = 1;
  //   }
  //
  // NOTE: the numeric '101' above must be an integer greater than 101
  // and must be unique across your code base.
  //
  // Given the above definition in your service protobuf file, you would
  // use this method like:
  //
  //   MyServiceError err;
  //   err.set_extra_error_data("foo bar");
  //   ctx->RespondApplicationError(MyServiceError::my_service_error_ext.number(),
  //                                "Some error occurred", err);
  //
  // The client side may then retreieve the error by calling:
  //   const MyServiceError& err_details =
  //     controller->error_response()->GetExtension(MyServiceError::my_service_error_ext);
  //
  // After this method returns, this RpcContext object is destroyed. The request
  // and response protobufs are also destroyed.
  void RespondApplicationError(int error_ext_id, const std::string& message,
                               const google::protobuf::Message& app_error_pb);


  // Adds an RpcSidecar to the response. This is the preferred method for
  // transferring large amounts of binary data, because this avoids additional
  // copies made by serializing the protobuf.
  //
  // Assumes no changes to the sidecar's data are made after insertion.
  //
  // Upon success, writes the index of the sidecar (necessary to be retrieved
  // later) to 'idx'. Call may fail if all sidecars have already been used
  // by the RPC response.
  Status AddOutboundSidecar(std::unique_ptr<RpcSidecar> car, int* idx);

  // Fills 'sidecar' with a sidecar sent by the client. Returns an error if 'idx' is out
  // of bounds.
  Status GetInboundSidecar(int idx, Slice* slice);

  // Return the identity of remote user who made this call.
  const RemoteUser& remote_user() const;

  // Whether it's OK to pass confidential information between the client and the
  // server in the context of the RPC call being handled.  In real world, this
  // translates into properties of the connection between the client and the
  // server. For example, this methods returns 'true' for a call over an
  // encrypted connection.
  bool is_confidential() const;

  // Discards the memory associated with the inbound call's payload. All previously
  // obtained sidecar slices will be invalidated by this call. It is an error to call
  // GetInboundSidecar() after this method. request_pb() remains valid.
  // This is useful in the case where the server wishes to delay responding to an RPC
  // (perhaps to control the rate of RPC requests), but knows that the RPC payload itself
  // won't be processed any further.
  void DiscardTransfer();

  // Return the remote IP address and port which sent the current RPC call.
  const Sockaddr& remote_address() const;

  // A string identifying the requestor -- both the user info and the IP address.
  // Suitable for use in log messages.
  std::string requestor_string() const;

  // Return the name of the RPC service method being called.
  std::string method_name() const;

  // Return the name of the RPC service being called.
  std::string service_name() const;

  const google::protobuf::Message *request_pb() const { return request_pb_.get(); }
  google::protobuf::Message *response_pb() const { return response_pb_.get(); }

  // Return an upper bound on the client timeout deadline. This does not
  // account for transmission delays between the client and the server.
  // If the client did not specify a deadline, returns MonoTime::Max().
  MonoTime GetClientDeadline() const;

  // Return the time when the inbound call was received.
  MonoTime GetTimeReceived() const;

  // Whether the results of this RPC are tracked with a ResultTracker.
  // If this returns true, both result_tracker() and request_id() should return non-null results.
  bool AreResultsTracked() const { return result_tracker_.get() != nullptr; }

  // Returns this call's result tracker, if it is set.
  const scoped_refptr<ResultTracker>& result_tracker() const {
    return result_tracker_;
  }

  // Returns this call's request id, if it is set.
  const rpc::RequestIdPB* request_id() const;

  // Returns the size of the transfer buffer that backs 'call_'. If the
  // transfer buffer no longer exists (e.g. GetTransferSize() is called after
  // DiscardTransfer()), returns 0.
  size_t GetTransferSize() const;

  // Panic the server. This logs a fatal error with the given message, and
  // also includes the current RPC request, requestor, trace information, etc,
  // to make it easier to debug.
  //
  // Call this via the PANIC_RPC() macro.
  void Panic(const char* filepath, int line_number, const std::string& message)
    __attribute__((noreturn));

 private:
  friend class ResultTracker;
  InboundCall* const call_;
  const gscoped_ptr<const google::protobuf::Message> request_pb_;
  const gscoped_ptr<google::protobuf::Message> response_pb_;
  scoped_refptr<ResultTracker> result_tracker_;
};

} // namespace rpc
} // namespace kudu
#endif
