// 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.
//
// This module is internal to the client and not a public API.
#pragma once

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

#include "kudu/gutil/port.h"
#include "kudu/gutil/ref_counted.h"
#include "kudu/master/master.pb.h"
#include "kudu/rpc/rpc.h"
#include "kudu/rpc/rpc_controller.h"
#include "kudu/rpc/user_credentials.h"
#include "kudu/util/locks.h"
#include "kudu/util/monotime.h"

namespace kudu {

class Sockaddr;
class Status;

namespace rpc {
class Messenger;
}

namespace client {
namespace internal {

// In parallel, send requests to the specified Master servers until a
// response comes back from the leader of the Master consensus configuration.
//
// In addition to locating the leader, this fetches cluster-wide details
// such as an authentication token for the current user, the cluster's
// CA cert, etc.
//
// If queries have been made to all of the specified servers, but no
// leader has been found, we re-try again (with an increasing delay,
// see: RpcRetrier in kudu/rpc/rpc.{cc,h}) until a specified deadline
// passes or we find a leader.
//
// The RPCs are sent in parallel in order to avoid prolonged delays on
// the client-side that would happen with a serial approach when one
// of the Master servers is slow or stopped (that is, when we have to
// wait for an RPC request to server N to timeout before we can make
// an RPC request to server N+1). This allows for true fault tolerance
// for the Kudu client.
//
// The class is reference counted to avoid a "use-after-free"
// scenario, when responses to the RPC return to the caller _after_ a
// leader has already been found.
class ConnectToClusterRpc : public rpc::Rpc,
                            public RefCountedThreadSafe<ConnectToClusterRpc> {
 public:
  typedef std::function<void(
      const Status& status,
      const std::pair<Sockaddr, std::string>& leader_master,
      const master::ConnectToMasterResponsePB& connect_response)> LeaderCallback;
  // The host and port of the leader master server is stored in
  // 'leader_master', which must remain valid for the lifetime of this
  // object.
  //
  // Calls 'user_cb' when the leader is found, or if no leader can be found
  // until 'deadline' passes. Each RPC has 'rpc_timeout' time to complete
  // before it times out and may be retried if 'deadline' has not yet passed.
  ConnectToClusterRpc(LeaderCallback user_cb,
                      std::vector<std::pair<Sockaddr, std::string>> addrs_with_names,
                      MonoTime deadline,
                      MonoDelta rpc_timeout,
                      std::shared_ptr<rpc::Messenger> messenger,
                      rpc::UserCredentials user_credentials,
                      rpc::CredentialsPolicy creds_policy =
      rpc::CredentialsPolicy::ANY_CREDENTIALS);

  virtual void SendRpc() OVERRIDE;

  virtual std::string ToString() const OVERRIDE;
 private:
  friend class RefCountedThreadSafe<ConnectToClusterRpc>;
  ~ConnectToClusterRpc();

  virtual void SendRpcCb(const Status& status) OVERRIDE;

  // Invoked when a response comes back from the master with index
  // 'master_idx'.
  //
  // Invokes SendRpcCb if the response indicates that the specified
  // master is a leader, or if responses have been received from all
  // of the Masters.
  void SingleNodeCallback(int master_idx, const Status& status);

  const LeaderCallback user_cb_;

  // The addresses of the masters, along with their original specified names.
  const std::vector<std::pair<Sockaddr, std::string>> addrs_with_names_;

  // The user credentials of the client.
  const rpc::UserCredentials user_credentials_;

  // The amount of time alloted to each GetMasterRegistration RPC.
  const MonoDelta rpc_timeout_;

  // The received responses. The indexes correspond to 'addrs_'.
  std::vector<master::ConnectToMasterResponsePB> responses_;

  // Number of pending responses.
  int pending_responses_;

  // If true, then we've already executed the user callback and the
  // RPC can be deallocated.
  bool completed_;

  // The index of the master that was determined to be the leader.
  // This corresponds to entries in 'responses_' and 'addrs_'.
  // -1 indicates no leader found.
  int leader_idx_ = -1;

  // Protects 'pending_responses_' and 'completed_'.
  mutable simple_spinlock lock_;
};

} // namespace internal
} // namespace client
} // namespace kudu
