/*
 *  Copyright 2019 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef P2P_BASE_CONNECTION_H_
#define P2P_BASE_CONNECTION_H_

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

#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/candidate.h"
#include "api/transport/stun.h"
#include "logging/rtc_event_log/ice_logger.h"
#include "p2p/base/candidate_pair_interface.h"
#include "p2p/base/connection_info.h"
#include "p2p/base/p2p_transport_channel_ice_field_trials.h"
#include "p2p/base/stun_request.h"
#include "p2p/base/transport_description.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/network.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/numerics/event_based_exponential_moving_average.h"
#include "rtc_base/rate_tracker.h"
#include "rtc_base/system/rtc_export.h"
#include "rtc_base/weak_ptr.h"

namespace cricket {

// Version number for GOOG_PING, this is added to have the option of
// adding other flavors in the future.
constexpr int kGoogPingVersion = 1;

// Connection and Port has circular dependencies.
// So we use forward declaration rather than include.
class Port;

// Forward declaration so that a ConnectionRequest can contain a Connection.
class Connection;

struct CandidatePair final : public CandidatePairInterface {
  ~CandidatePair() override = default;

  const Candidate& local_candidate() const override { return local; }
  const Candidate& remote_candidate() const override { return remote; }

  Candidate local;
  Candidate remote;
};

// Represents a communication link between a port on the local client and a
// port on the remote client.
class RTC_EXPORT Connection : public CandidatePairInterface {
 public:
  struct SentPing {
    SentPing(absl::string_view id, int64_t sent_time, uint32_t nomination)
        : id(id), sent_time(sent_time), nomination(nomination) {}

    std::string id;
    int64_t sent_time;
    uint32_t nomination;
  };

  ~Connection() override;

  // A unique ID assigned when the connection is created.
  uint32_t id() const { return id_; }

  webrtc::TaskQueueBase* network_thread() const;

  // Implementation of virtual methods in CandidatePairInterface.
  // Returns the description of the local port
  const Candidate& local_candidate() const override;
  // Returns the description of the remote port to which we communicate.
  const Candidate& remote_candidate() const override;

  // Return local network for this connection.
  virtual const rtc::Network* network() const;
  // Return generation for this connection.
  virtual int generation() const;

  // Returns the pair priority.
  virtual uint64_t priority() const;

  enum WriteState {
    STATE_WRITABLE = 0,          // we have received ping responses recently
    STATE_WRITE_UNRELIABLE = 1,  // we have had a few ping failures
    STATE_WRITE_INIT = 2,        // we have yet to receive a ping response
    STATE_WRITE_TIMEOUT = 3,     // we have had a large number of ping failures
  };

  WriteState write_state() const;
  bool writable() const;
  bool receiving() const;

  const Port* port() const {
    RTC_DCHECK_RUN_ON(network_thread_);
    return port_.get();
  }

  // Determines whether the connection has finished connecting.  This can only
  // be false for TCP connections.
  bool connected() const;
  bool weak() const;
  bool active() const;
  bool pending_delete() const { return !port_; }

  // A connection is dead if it can be safely deleted.
  bool dead(int64_t now) const;

  // Estimate of the round-trip time over this connection.
  int rtt() const;

  int unwritable_timeout() const;
  void set_unwritable_timeout(const absl::optional<int>& value_ms);
  int unwritable_min_checks() const;
  void set_unwritable_min_checks(const absl::optional<int>& value);
  int inactive_timeout() const;
  void set_inactive_timeout(const absl::optional<int>& value);

  // Gets the `ConnectionInfo` stats, where `best_connection` has not been
  // populated (default value false).
  ConnectionInfo stats();

  sigslot::signal1<Connection*> SignalStateChange;

  // Sent when the connection has decided that it is no longer of value.  It
  // will delete itself immediately after this call.
  sigslot::signal1<Connection*> SignalDestroyed;

  // The connection can send and receive packets asynchronously.  This matches
  // the interface of AsyncPacketSocket, which may use UDP or TCP under the
  // covers.
  virtual int Send(const void* data,
                   size_t size,
                   const rtc::PacketOptions& options) = 0;

  // Error if Send() returns < 0
  virtual int GetError() = 0;

  // Register as a recipient of received packets. There can only be one.
  void RegisterReceivedPacketCallback(
      absl::AnyInvocable<void(Connection*, const rtc::ReceivedPacket&)>
          received_packet_callback);
  void DeregisterReceivedPacketCallback();

  sigslot::signal1<Connection*> SignalReadyToSend;

  // Called when a packet is received on this connection.
  void OnReadPacket(const rtc::ReceivedPacket& packet);
  [[deprecated("Pass a rtc::ReceivedPacket")]] void
  OnReadPacket(const char* data, size_t size, int64_t packet_time_us);

  // Called when the socket is currently able to send.
  void OnReadyToSend();

  // Called when a connection is determined to be no longer useful to us.  We
  // still keep it around in case the other side wants to use it.  But we can
  // safely stop pinging on it and we can allow it to time out if the other
  // side stops using it as well.
  bool pruned() const;
  void Prune();

  bool use_candidate_attr() const;
  void set_use_candidate_attr(bool enable);

  void set_nomination(uint32_t value);

  uint32_t remote_nomination() const;
  // One or several pairs may be nominated based on if Regular or Aggressive
  // Nomination is used. https://tools.ietf.org/html/rfc5245#section-8
  // `nominated` is defined both for the controlling or controlled agent based
  // on if a nomination has been pinged or acknowledged. The controlled agent
  // gets its `remote_nomination_` set when pinged by the controlling agent with
  // a nomination value. The controlling agent gets its `acked_nomination_` set
  // when receiving a response to a nominating ping.
  bool nominated() const;

  int receiving_timeout() const;
  void set_receiving_timeout(absl::optional<int> receiving_timeout_ms);

  // Deletes a `Connection` instance is by calling the `DestroyConnection`
  // method in `Port`.
  // Note: When the function returns, the object has been deleted.
  void Destroy();

  // Signals object destruction, releases outstanding references and performs
  // final logging.
  // The function will return `true` when shutdown was performed, signals
  // emitted and outstanding references released. If the function returns
  // `false`, `Shutdown()` has previously been called.
  bool Shutdown();

  // Prunes the connection and sets its state to STATE_FAILED,
  // It will not be used or send pings although it can still receive packets.
  void FailAndPrune();

  // Checks that the state of this connection is up-to-date.  The argument is
  // the current time, which is compared against various timeouts.
  void UpdateState(int64_t now);

  void UpdateLocalIceParameters(int component,
                                absl::string_view username_fragment,
                                absl::string_view password);

  // Called when this connection should try checking writability again.
  int64_t last_ping_sent() const;
  void Ping(int64_t now,
            std::unique_ptr<StunByteStringAttribute> delta = nullptr);
  void ReceivedPingResponse(
      int rtt,
      absl::string_view request_id,
      const absl::optional<uint32_t>& nomination = absl::nullopt);
  std::unique_ptr<IceMessage> BuildPingRequest(
      std::unique_ptr<StunByteStringAttribute> delta)
      RTC_RUN_ON(network_thread_);

  int64_t last_ping_response_received() const;
  const absl::optional<std::string>& last_ping_id_received() const;

  // Used to check if any STUN ping response has been received.
  int rtt_samples() const;

  // Called whenever a valid ping is received on this connection.  This is
  // public because the connection intercepts the first ping for us.
  int64_t last_ping_received() const;

  void ReceivedPing(
      const absl::optional<std::string>& request_id = absl::nullopt);
  // Handles the binding request; sends a response if this is a valid request.
  void HandleStunBindingOrGoogPingRequest(IceMessage* msg);
  // Handles the piggyback acknowledgement of the lastest connectivity check
  // that the remote peer has received, if it is indicated in the incoming
  // connectivity check from the peer.
  void HandlePiggybackCheckAcknowledgementIfAny(StunMessage* msg);
  // Timestamp when data was last sent (or attempted to be sent).
  int64_t last_send_data() const;
  int64_t last_data_received() const;

  // Debugging description of this connection
  std::string ToDebugId() const;
  std::string ToString() const;
  std::string ToSensitiveString() const;
  // Structured description of this candidate pair.
  const webrtc::IceCandidatePairDescription& ToLogDescription();
  void set_ice_event_log(webrtc::IceEventLog* ice_event_log);

  // Prints pings_since_last_response_ into a string.
  void PrintPingsSinceLastResponse(std::string* pings, size_t max);

  // `set_selected` is only used for logging in ToString above.  The flag is
  // set true by P2PTransportChannel for its selected candidate pair.
  // TODO(tommi): Remove `selected()` once not referenced downstream.
  bool selected() const;
  void set_selected(bool selected);

  // This signal will be fired if this connection is nominated by the
  // controlling side.
  sigslot::signal1<Connection*> SignalNominated;

  IceCandidatePairState state() const;

  int num_pings_sent() const;

  uint32_t ComputeNetworkCost() const;

  // Update the ICE password and/or generation of the remote candidate if the
  // ufrag in `params` matches the candidate's ufrag, and the
  // candidate's password and/or ufrag has not been set.
  void MaybeSetRemoteIceParametersAndGeneration(const IceParameters& params,
                                                int generation);

  // If `remote_candidate_` is peer reflexive and is equivalent to
  // `new_candidate` except the type, update `remote_candidate_` to
  // `new_candidate`.
  void MaybeUpdatePeerReflexiveCandidate(const Candidate& new_candidate);

  // Returns the last received time of any data, stun request, or stun
  // response in milliseconds
  int64_t last_received() const;
  // Returns the last time when the connection changed its receiving state.
  int64_t receiving_unchanged_since() const;

  // Constructs the prflx priority as described in
  // https://datatracker.ietf.org/doc/html/rfc5245#section-4.1.2.1
  uint32_t prflx_priority() const;

  bool stable(int64_t now) const;

  // Check if we sent `val` pings without receving a response.
  bool TooManyOutstandingPings(const absl::optional<int>& val) const;

  // Called by Port when the network cost changes.
  void SetLocalCandidateNetworkCost(uint16_t cost);

  void SetIceFieldTrials(const IceFieldTrials* field_trials);
  const rtc::EventBasedExponentialMovingAverage& GetRttEstimate() const {
    return rtt_estimate_;
  }

  // Reset the connection to a state of a newly connected.
  // - STATE_WRITE_INIT
  // - receving = false
  // - throw away all pending request
  // - reset RttEstimate
  //
  // Keep the following unchanged:
  // - connected
  // - remote_candidate
  // - statistics
  //
  // Does not trigger SignalStateChange
  void ForgetLearnedState();

  void SendStunBindingResponse(const StunMessage* message);
  void SendGoogPingResponse(const StunMessage* message);
  void SendResponseMessage(const StunMessage& response);

  // An accessor for unit tests.
  Port* PortForTest() { return port_.get(); }
  const Port* PortForTest() const { return port_.get(); }

  std::unique_ptr<IceMessage> BuildPingRequestForTest() {
    RTC_DCHECK_RUN_ON(network_thread_);
    return BuildPingRequest(nullptr);
  }

  // Public for unit tests.
  uint32_t acked_nomination() const;
  void set_remote_nomination(uint32_t remote_nomination);

  const std::string& remote_password_for_test() const {
    return remote_candidate().password();
  }
  void set_remote_password_for_test(absl::string_view pwd) {
    remote_candidate_.set_password(pwd);
  }

  void SetStunDictConsumer(
      std::function<std::unique_ptr<StunAttribute>(
          const StunByteStringAttribute*)> goog_delta_consumer,
      std::function<void(webrtc::RTCErrorOr<const StunUInt64Attribute*>)>
          goog_delta_ack_consumer) {
    goog_delta_consumer_ = std::move(goog_delta_consumer);
    goog_delta_ack_consumer_ = std::move(goog_delta_ack_consumer);
  }

  void ClearStunDictConsumer() {
    goog_delta_consumer_ = absl::nullopt;
    goog_delta_ack_consumer_ = absl::nullopt;
  }

 protected:
  // A ConnectionRequest is a simple STUN ping used to determine writability.
  class ConnectionRequest;

  // Constructs a new connection to the given remote port.
  Connection(rtc::WeakPtr<Port> port, size_t index, const Candidate& candidate);

  // Called back when StunRequestManager has a stun packet to send
  void OnSendStunPacket(const void* data, size_t size, StunRequest* req);

  // Callbacks from ConnectionRequest
  virtual void OnConnectionRequestResponse(StunRequest* req,
                                           StunMessage* response);
  void OnConnectionRequestErrorResponse(ConnectionRequest* req,
                                        StunMessage* response)
      RTC_RUN_ON(network_thread_);
  void OnConnectionRequestTimeout(ConnectionRequest* req)
      RTC_RUN_ON(network_thread_);
  void OnConnectionRequestSent(ConnectionRequest* req)
      RTC_RUN_ON(network_thread_);

  bool rtt_converged() const;

  // If the response is not received within 2 * RTT, the response is assumed to
  // be missing.
  bool missing_responses(int64_t now) const;

  // Changes the state and signals if necessary.
  void set_write_state(WriteState value);
  void UpdateReceiving(int64_t now);
  void set_state(IceCandidatePairState state);
  void set_connected(bool value);

  // The local port where this connection sends and receives packets.
  Port* port() { return port_.get(); }

  // NOTE: A pointer to the network thread is held by `port_` so in theory we
  // shouldn't need to hold on to this pointer here, but rather defer to
  // port_->thread(). However, some tests delete the classes in the wrong order
  // so `port_` may be deleted before an instance of this class is deleted.
  // TODO(tommi): This ^^^ should be fixed.
  webrtc::TaskQueueBase* const network_thread_;
  const uint32_t id_;
  rtc::WeakPtr<Port> port_;
  Candidate local_candidate_ RTC_GUARDED_BY(network_thread_);
  Candidate remote_candidate_;

  ConnectionInfo stats_;
  rtc::RateTracker recv_rate_tracker_;
  rtc::RateTracker send_rate_tracker_;
  int64_t last_send_data_ = 0;

 private:
  // Update the local candidate based on the mapped address attribute.
  // If the local candidate changed, fires SignalStateChange.
  void MaybeUpdateLocalCandidate(StunRequest* request, StunMessage* response)
      RTC_RUN_ON(network_thread_);

  void LogCandidatePairConfig(webrtc::IceCandidatePairConfigType type)
      RTC_RUN_ON(network_thread_);
  void LogCandidatePairEvent(webrtc::IceCandidatePairEventType type,
                             uint32_t transaction_id)
      RTC_RUN_ON(network_thread_);

  // Check if this IceMessage is identical
  // to last message ack:ed STUN_BINDING_REQUEST.
  bool ShouldSendGoogPing(const StunMessage* message)
      RTC_RUN_ON(network_thread_);

  WriteState write_state_ RTC_GUARDED_BY(network_thread_);
  bool receiving_ RTC_GUARDED_BY(network_thread_);
  bool connected_ RTC_GUARDED_BY(network_thread_);
  bool pruned_ RTC_GUARDED_BY(network_thread_);
  bool selected_ RTC_GUARDED_BY(network_thread_) = false;
  // By default `use_candidate_attr_` flag will be true,
  // as we will be using aggressive nomination.
  // But when peer is ice-lite, this flag "must" be initialized to false and
  // turn on when connection becomes "best connection".
  bool use_candidate_attr_ RTC_GUARDED_BY(network_thread_);
  // Used by the controlling side to indicate that this connection will be
  // selected for transmission if the peer supports ICE-renomination when this
  // value is positive. A larger-value indicates that a connection is nominated
  // later and should be selected by the controlled side with higher precedence.
  // A zero-value indicates not nominating this connection.
  uint32_t nomination_ RTC_GUARDED_BY(network_thread_) = 0;
  // The last nomination that has been acknowledged.
  uint32_t acked_nomination_ RTC_GUARDED_BY(network_thread_) = 0;
  // Used by the controlled side to remember the nomination value received from
  // the controlling side. When the peer does not support ICE re-nomination, its
  // value will be 1 if the connection has been nominated.
  uint32_t remote_nomination_ RTC_GUARDED_BY(network_thread_) = 0;

  StunRequestManager requests_ RTC_GUARDED_BY(network_thread_);
  int rtt_ RTC_GUARDED_BY(network_thread_);
  int rtt_samples_ RTC_GUARDED_BY(network_thread_) = 0;
  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
  uint64_t total_round_trip_time_ms_ RTC_GUARDED_BY(network_thread_) = 0;
  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
  absl::optional<uint32_t> current_round_trip_time_ms_
      RTC_GUARDED_BY(network_thread_);
  int64_t last_ping_sent_ RTC_GUARDED_BY(
      network_thread_);  // last time we sent a ping to the other side
  int64_t last_ping_received_
      RTC_GUARDED_BY(network_thread_);  // last time we received a ping from the
                                        // other side
  int64_t last_data_received_ RTC_GUARDED_BY(network_thread_);
  int64_t last_ping_response_received_ RTC_GUARDED_BY(network_thread_);
  int64_t receiving_unchanged_since_ RTC_GUARDED_BY(network_thread_) = 0;
  std::vector<SentPing> pings_since_last_response_
      RTC_GUARDED_BY(network_thread_);
  // Transaction ID of the last connectivity check received. Null if having not
  // received a ping yet.
  absl::optional<std::string> last_ping_id_received_
      RTC_GUARDED_BY(network_thread_);

  absl::optional<int> unwritable_timeout_ RTC_GUARDED_BY(network_thread_);
  absl::optional<int> unwritable_min_checks_ RTC_GUARDED_BY(network_thread_);
  absl::optional<int> inactive_timeout_ RTC_GUARDED_BY(network_thread_);

  IceCandidatePairState state_ RTC_GUARDED_BY(network_thread_);
  // Time duration to switch from receiving to not receiving.
  absl::optional<int> receiving_timeout_ RTC_GUARDED_BY(network_thread_);
  const int64_t time_created_ms_ RTC_GUARDED_BY(network_thread_);
  const int64_t delta_internal_unix_epoch_ms_ RTC_GUARDED_BY(network_thread_);
  int num_pings_sent_ RTC_GUARDED_BY(network_thread_) = 0;

  absl::optional<webrtc::IceCandidatePairDescription> log_description_
      RTC_GUARDED_BY(network_thread_);
  webrtc::IceEventLog* ice_event_log_ RTC_GUARDED_BY(network_thread_) = nullptr;

  // GOOG_PING_REQUEST is sent in place of STUN_BINDING_REQUEST
  // if configured via field trial, the remote peer supports it (signaled
  // in STUN_BINDING) and if the last STUN BINDING is identical to the one
  // that is about to be sent.
  absl::optional<bool> remote_support_goog_ping_
      RTC_GUARDED_BY(network_thread_);
  std::unique_ptr<StunMessage> cached_stun_binding_
      RTC_GUARDED_BY(network_thread_);

  const IceFieldTrials* field_trials_;
  rtc::EventBasedExponentialMovingAverage rtt_estimate_
      RTC_GUARDED_BY(network_thread_);

  absl::optional<std::function<std::unique_ptr<StunAttribute>(
      const StunByteStringAttribute*)>>
      goog_delta_consumer_;
  absl::optional<
      std::function<void(webrtc::RTCErrorOr<const StunUInt64Attribute*>)>>
      goog_delta_ack_consumer_;
  absl::AnyInvocable<void(Connection*, const rtc::ReceivedPacket&)>
      received_packet_callback_;
};

// ProxyConnection defers all the interesting work to the port.
class ProxyConnection : public Connection {
 public:
  ProxyConnection(rtc::WeakPtr<Port> port,
                  size_t index,
                  const Candidate& remote_candidate);

  int Send(const void* data,
           size_t size,
           const rtc::PacketOptions& options) override;
  int GetError() override;

 private:
  int error_ = 0;
};

}  // namespace cricket

#endif  // P2P_BASE_CONNECTION_H_
