// Copyright 2017 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 COBALT_ENCODER_SEND_RETRYER_H_
#define COBALT_ENCODER_SEND_RETRYER_H_

#include <memory>

#include "encoder/shuffler_client.h"
#include "util/clock.h"

namespace cobalt {
namespace encoder {

namespace send_retryer {

// An object that provides a way to cancel an invocation of SendToShuffler().
class CancelHandle;

// An abstract interface implemented by SendRetryer (below).
// This is abstracted so that it may be mocked in tests.
class SendRetryerInterface {
 public:
  virtual ~SendRetryerInterface() = default;

  virtual grpc::Status SendToShuffler(
      std::chrono::seconds initial_rpc_deadline,
      std::chrono::seconds overerall_deadline,
      send_retryer::CancelHandle* cancel_handle,
      const EncryptedMessage& encrypted_message) = 0;
};

// This class wraps a ShufflerClient with retry logic. We categorize
// gRPC error statuses as either retryable or not. If an error is retryable
// then we retry with exponential backoff, otherwise we give up. If the
// returned error is DEADLINE_EXEEDED then we increase the deadline.
class SendRetryer : public SendRetryerInterface {
 public:
  // Does not take ownership of |shuffler_client|.
  explicit SendRetryer(ShufflerClientInterface* shuffler_client);

  virtual ~SendRetryer() = default;

  // Uses the wrapped ShufflerClient to send the given |encrypted_message| to
  // the Shuffler. It should be an encrypted Envelope as given by the output of
  // EnvelopeMaker::MakeEncryptedEnvelope().
  //
  // |inital_rpc_deadline| is the gRPC deadline to use for the first send
  // attempt. This must be positive or we will CHECK fail. The deadline will be
  // increased in later attempts if a DEADLINE_EXCEEDED status code is returned
  // from the Shuffler. We will not honor arbitrarily large values of this
  // parameter: We will truncate to a reasonable upper bound for all
  // RPC timeouts.
  //
  // |overall_deadline| is the overall deadline granted to the Retryer for its
  // multiple attempts to send. This  must be >= |initial_rpc_deadline| or
  // we will CHECK fail. This may be set to std::chrono::seconds:max()
  // and the Retryer will retry "forever". Normally this should not be set
  // to less than about a minute in order to give the Retryer enough time
  // to try multiple times with increasing timeouts.
  //
  // |cancel_handle|. An optional pointer to an object that allows for
  // cancellation. This may be NULL but if it is not NULL then it must remain
  // valid for the duration of the call. Does not take ownership of
  // |cancel_handle|.
  //
  // This is a synchronous method that may take a long time to return
  // as the Retryer performs multiple attempts to send with exponential
  // backoff. This method will return when one of the following occurs:
  //
  // - A successful send. Returns OK.
  //
  // - A non-retryable status code is received from the shuffler. Returns
  //   that status code.
  //
  // - |overall_deadline| has been exceeded. Returns DEADLINE_EXCEEDED.
  //
  // - TryCancel() is invoked (from some other thread) on the provided
  //   |cancel_handle|. May return CANCELLED in this case if the call
  //   was successfully canceled. Other responses including OK are possible
  //   after a TryCancel() because the cancellation is not guaranteed.
  grpc::Status SendToShuffler(
      std::chrono::seconds initial_rpc_deadline,
      std::chrono::seconds overerall_deadline,
      send_retryer::CancelHandle* cancel_handle,
      const EncryptedMessage& encrypted_message) override;

 private:
  friend class SendRetryerTest;

  ShufflerClientInterface* shuffler_client_;  // not owned

  // The value with which we will initialize sleep_between_attempts. This
  // is exposed to friend tests so that they can set it to a smaller value.
  std::chrono::milliseconds initial_sleep_ = std::chrono::milliseconds(1000);

  // The clock is abstracted so that friend tests can set a non-system clock.
  std::unique_ptr<util::ClockInterface> clock_;
};

// An object that provides a way to cancel an invocation of SendToShuffler().
class CancelHandle {
 public:
  // Attempt to cancel the call. This may or may not succeed depending on
  // the current state of the call. If the Retryer is currently blocked
  // waiting for a retry then this will succeed. If a gRPC call is in-flight
  // an attempt will be made to cancel it but this may not succeed.
  void TryCancel();

 private:
  friend class SendRetryer;
  friend class SendRetryerTest;

  std::mutex mutex_;
  bool cancelled_ = false;
  std::condition_variable cancel_notifier_;
  std::unique_ptr<grpc::ClientContext> context_;

  // If this is not NULL then it will be invoked with the value
  // |sleep_millis| just prior to a sleep of |sleep_millis| milliseconds
  // commencing. This is only used for tests so far but may prove useful
  // for other purposes in the future.
  std::function<void(int)> sleep_notification_function_;
};

}  // namespace send_retryer
}  // namespace encoder
}  // namespace cobalt

#endif  // COBALT_ENCODER_SEND_RETRYER_H_
