// Copyright 2019 The Chromium 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 REMOTING_HOST_HEARTBEAT_SENDER_H_
#define REMOTING_HOST_HEARTBEAT_SENDER_H_

#include <memory>
#include <string>

#include "base/callback.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "base/timer/timer.h"
#include "net/base/backoff_entry.h"
#include "remoting/proto/remoting/v1/directory_messages.pb.h"
#include "remoting/signaling/signal_strategy.h"

namespace base {
class TimeDelta;
}  // namespace base

namespace network {
class SharedURLLoaderFactory;
}  // namespace network

namespace remoting {

class OAuthTokenGetter;
class ProtobufHttpStatus;

// HeartbeatSender periodically sends heartbeat to the directory service. See
// the HeartbeatRequest message in directory_messages.proto for more details.
//
// Normally the heartbeat indicates that the host is healthy and ready to
// accept new connections from a client, but the message can optionally include
// a host_offline_reason field, which indicates that the host cannot accept
// connections from the client (and might possibly be shutting down).  The value
// of the host_offline_reason field can be either a string from
// host_exit_codes.cc (i.e. "INVALID_HOST_CONFIGURATION" string) or one of
// kHostOfflineReasonXxx constants (i.e. "POLICY_READ_ERROR" string).
//
// The heartbeat sender will verify that the channel is in fact active before
// sending out the heartbeat. If not, it will disconnect the signaling strategy
// so that the signaling connector will try to reconnect signaling.
//
// The server sends a HeartbeatResponse in response to each successful
// heartbeat.
class HeartbeatSender final : public SignalStrategy::Listener {
 public:
  class Delegate {
   public:
    virtual ~Delegate() = default;

    // Invoked after the first successful heartbeat.
    virtual void OnFirstHeartbeatSuccessful() = 0;

    // Invoked when the host is not found in the directory.
    virtual void OnHostNotFound() = 0;

    // Invoked when the heartbeat sender permanently fails to authenticate the
    // requests.
    virtual void OnAuthFailed() = 0;

   protected:
    Delegate() = default;
  };

  // Interface to track heartbeat events for diagnosis purpose.
  class Observer {
   public:
    virtual ~Observer() = default;

    // Invoked when the heartbeat sender has sent a heartbeat.
    virtual void OnHeartbeatSent() = 0;

   protected:
    Observer() = default;
  };

  // All raw pointers must be non-null and outlive this object.
  HeartbeatSender(
      Delegate* delegate,
      const std::string& host_id,
      SignalStrategy* signal_strategy,
      OAuthTokenGetter* oauth_token_getter,
      Observer* observer,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      bool is_googler);
  ~HeartbeatSender() override;

  // Sets host offline reason for future heartbeat, and initiates sending a
  // heartbeat right away.
  //
  // For discussion of allowed values for |host_offline_reason| argument,
  // please see the description in the class-level comments above.
  //
  // |ack_callback| will be called when the server acks receiving the
  // |host_offline_reason| or when |timeout| is reached.
  void SetHostOfflineReason(
      const std::string& host_offline_reason,
      const base::TimeDelta& timeout,
      base::OnceCallback<void(bool success)> ack_callback);

 private:
  class HeartbeatClient {
   public:
    using HeartbeatResponseCallback =
        base::OnceCallback<void(const ProtobufHttpStatus&,
                                std::unique_ptr<apis::v1::HeartbeatResponse>)>;

    virtual ~HeartbeatClient() = default;

    virtual void Heartbeat(std::unique_ptr<apis::v1::HeartbeatRequest> request,
                           HeartbeatResponseCallback callback) = 0;
    virtual void CancelPendingRequests() = 0;
  };

  class HeartbeatClientImpl;

  friend class HeartbeatSenderTest;

  // SignalStrategy::Listener interface.
  void OnSignalStrategyStateChange(SignalStrategy::State state) override;
  bool OnSignalStrategyIncomingStanza(
      const jingle_xmpp::XmlElement* stanza) override;

  void SendHeartbeat();
  void OnResponse(const ProtobufHttpStatus& status,
                  std::unique_ptr<apis::v1::HeartbeatResponse> response);

  // Handlers for host-offline-reason completion and timeout.
  void OnHostOfflineReasonTimeout();
  void OnHostOfflineReasonAck();

  // Helper methods used by DoSendStanza() to generate heartbeat stanzas.
  std::unique_ptr<apis::v1::HeartbeatRequest> CreateHeartbeatRequest();

  Delegate* delegate_;
  std::string host_id_;
  SignalStrategy* const signal_strategy_;
  std::unique_ptr<HeartbeatClient> client_;
  OAuthTokenGetter* const oauth_token_getter_;
  Observer* observer_;

  base::OneShotTimer heartbeat_timer_;

  net::BackoffEntry backoff_;

  bool initial_heartbeat_sent_ = false;

  bool is_googler_ = false;

  // Fields to send and indicate completion of sending host-offline-reason.
  std::string host_offline_reason_;
  base::OnceCallback<void(bool success)> host_offline_reason_ack_callback_;
  base::OneShotTimer host_offline_reason_timeout_timer_;

  SEQUENCE_CHECKER(sequence_checker_);

  DISALLOW_COPY_AND_ASSIGN(HeartbeatSender);
};

}  // namespace remoting

#endif  // REMOTING_HOST_HEARTBEAT_SENDER_H_
