/*
 *  Copyright 2004 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_PORT_H_
#define P2P_BASE_PORT_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <span>
#include <string>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/candidate.h"
#include "api/environment/environment.h"
#include "api/local_network_access_permission.h"
#include "api/packet_socket_factory.h"
#include "api/sequence_checker.h"
#include "api/task_queue/task_queue_base.h"
#include "api/transport/stun.h"
#include "p2p/base/candidate_pair_interface.h"
#include "p2p/base/connection.h"
#include "p2p/base/p2p_constants.h"  // IWYU pragma: keep
#include "p2p/base/port_interface.h"
#include "p2p/base/transport_description.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/callback_list.h"
#include "rtc_base/dscp.h"
#include "rtc_base/net_helper.h"
#include "rtc_base/network.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/network/sent_packet.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/system/rtc_export.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/weak_ptr.h"

namespace webrtc {

enum class MdnsNameRegistrationStatus {
  // IP concealment with mDNS is not enabled or the name registration process is
  // not started yet.
  kNotStarted,
  // A request to create and register an mDNS name for a local IP address of a
  // host candidate is sent to the mDNS responder.
  kInProgress,
  // The name registration is complete and the created name is returned by the
  // mDNS responder.
  kCompleted,
};

// Stats that we can return about the port of a STUN candidate.
class StunStats {
 public:
  StunStats() = default;
  StunStats(const StunStats&) = default;
  ~StunStats() = default;

  StunStats& operator=(const StunStats& other) = default;

  int stun_binding_requests_sent = 0;
  int stun_binding_responses_received = 0;
  double stun_binding_rtt_ms_total = 0;
  double stun_binding_rtt_ms_squared_total = 0;
};

// Stats that we can return about a candidate.
class CandidateStats {
 public:
  CandidateStats() = default;
  CandidateStats(const CandidateStats&) = default;
  CandidateStats(CandidateStats&&) = default;
  CandidateStats(Candidate candidate,
                 std::optional<StunStats> stats = std::nullopt)
      : candidate_(std::move(candidate)), stun_stats_(std::move(stats)) {}
  ~CandidateStats() = default;

  CandidateStats& operator=(const CandidateStats& other) = default;

  const Candidate& candidate() const { return candidate_; }

  const std::optional<StunStats>& stun_stats() const { return stun_stats_; }

 private:
  Candidate candidate_;
  // STUN port stats if this candidate is a STUN candidate.
  std::optional<StunStats> stun_stats_;
};

typedef std::vector<CandidateStats> CandidateStatsList;

struct ProtocolAddress {
  SocketAddress address;
  ProtocolType proto;

  ProtocolAddress(const SocketAddress& a, ProtocolType p)
      : address(a), proto(p) {}

  bool operator==(const ProtocolAddress& o) const {
    return address == o.address && proto == o.proto;
  }
  bool operator!=(const ProtocolAddress& o) const { return !(*this == o); }
};

struct IceCandidateErrorEvent {
  IceCandidateErrorEvent() = default;
  IceCandidateErrorEvent(absl::string_view address,
                         int port,
                         absl::string_view url,
                         int error_code,
                         absl::string_view error_text)
      : address(std::move(address)),
        port(port),
        url(std::move(url)),
        error_code(error_code),
        error_text(std::move(error_text)) {}

  std::string address;
  int port = 0;
  std::string url;
  int error_code = 0;
  std::string error_text;
};

struct CandidatePairChangeEvent {
  std::string transport_name;
  CandidatePair selected_candidate_pair;
  int64_t last_data_received_ms;
  std::string reason;
  // How long do we estimate that we've been disconnected.
  int64_t estimated_disconnected_time_ms;
};

typedef std::set<SocketAddress> ServerAddresses;

// Represents a local communication mechanism that can be used to create
// connections to similar mechanisms of the other client.  Subclasses of this
// one add support for specific mechanisms like local UDP ports.
class RTC_EXPORT Port : public PortInterface {
 public:
  // A struct containing common arguments to creating a port. See also
  // CreateRelayPortArgs.
  struct PortParametersRef {
    Environment env;
    TaskQueueBase* network_thread;
    PacketSocketFactory* socket_factory;
    const ::webrtc::Network* network;
    absl::string_view ice_username_fragment;
    absl::string_view ice_password;
    absl::string_view content_name;
    LocalNetworkAccessPermissionFactoryInterface* lna_permission_factory =
        nullptr;
  };

 protected:
  // Constructors for use only by via constructors in derived classes.
  Port(const PortParametersRef& args, IceCandidateType type);
  Port(const PortParametersRef& args,
       IceCandidateType type,
       uint16_t min_port,
       uint16_t max_port,
       bool shared_socket = false);

 public:
  ~Port() override;

  // Note that the port type does NOT uniquely identify different subclasses of
  // Port. Use the 2-tuple of the port type AND the protocol (GetProtocol()) to
  // uniquely identify subclasses. Whenever a new subclass of Port introduces a
  // conflict in the value of the 2-tuple, make sure that the implementation
  // that relies on this 2-tuple for RTTI is properly changed.
  IceCandidateType Type() const override;
  const ::webrtc::Network* Network() const override;

  // Methods to set/get ICE role and tiebreaker values.
  IceRole GetIceRole() const override;
  void SetIceRole(IceRole role) override;

  /*
  int SendTo(std::span<const uint8_t> data,
             const SocketAddress& addr,
             const AsyncSocketPacketOptions& options,
             bool payload) override = 0;
  */

  void SetIceTiebreaker(uint64_t tiebreaker) override;
  uint64_t IceTiebreaker() const override;

  bool SharedSocket() const override;
  void ResetSharedSocket() {
    RTC_DCHECK_RUN_ON(thread_);
    shared_socket_ = false;
  }

  // Should not destroy the port even if no connection is using it. Called when
  // a port is ready to use.
  void KeepAliveUntilPruned();
  // Allows a port to be destroyed if no connection is using it.
  void Prune();

  // Call to stop any currently pending operations from running.
  void CancelPendingTasks();

  // The thread on which this port performs its I/O.
  TaskQueueBase* thread() override { return thread_; }

  // The factory used to create the sockets of this port.
  PacketSocketFactory* socket_factory() const override { return factory_; }

  // For debugging purposes.
  const std::string& content_name() const override { return content_name_; }
  void set_content_name(absl::string_view content_name) {
    RTC_DCHECK_RUN_ON(thread_);
    content_name_ = std::string(content_name);
  }

  int component() const {
    RTC_DCHECK_RUN_ON(thread_);
    return component_;
  }
  void set_component(int component) {
    RTC_DCHECK_RUN_ON(thread_);
    component_ = component;
  }

  bool send_retransmit_count_attribute() const override {
    RTC_DCHECK_RUN_ON(thread_);
    return send_retransmit_count_attribute_;
  }
  void set_send_retransmit_count_attribute(bool enable) {
    RTC_DCHECK_RUN_ON(thread_);
    send_retransmit_count_attribute_ = enable;
  }

  // Identifies the generation that this port was created in.
  uint32_t generation() const override {
    RTC_DCHECK_RUN_ON(thread_);
    return generation_;
  }
  void set_generation(uint32_t generation) override {
    RTC_DCHECK_RUN_ON(thread_);
    generation_ = generation;
  }

  const std::string& username_fragment() const;
  const std::string& password() const { return password_; }

  // May be called when this port was initially created by a pooled
  // PortAllocatorSession, and is now being assigned to an ICE transport.
  // Updates the information for candidates as well.
  void SetIceParameters(int component,
                        absl::string_view username_fragment,
                        absl::string_view password);

  // Fired when candidates are discovered by the port. When all candidates
  // are discovered that belong to port SignalAddressReady is fired.
  [[deprecated("Use SubscribeCandidateReadyCallback(const void* tag, ...)")]]
  void SubscribeCandidateReadyCallback(
      absl::AnyInvocable<void(Port*, const Candidate&)> callback);
  void SubscribeCandidateReadyCallback(
      const void* tag,
      absl::AnyInvocable<void(Port*, const Candidate&)> callback);
  void NotifyCandidateReady(Port* port, const Candidate& candidate) {
    RTC_DCHECK_RUN_ON(thread_);
    candidate_ready_callback_list_.Send(this, candidate);
  }
  // Provides all of the above information in one handy object.
  const std::vector<Candidate>& Candidates() const override;
  // Fired when candidate discovery failed using certain server.
  [[deprecated("Use SubscribeCandidateError(const void* tag, ...)")]]
  void SubscribeCandidateError(
      std::function<void(Port*, const IceCandidateErrorEvent&)> callback);
  void SubscribeCandidateError(
      const void* tag,
      std::function<void(Port*, const IceCandidateErrorEvent&)> callback);
  void SendCandidateError(const IceCandidateErrorEvent& candidate_error_event);

  // SignalPortComplete is sent when port completes the task of candidates
  // allocation.
  [[deprecated("Use SubscribePortComplete(const void* tag, ...)")]]
  void SubscribePortComplete(absl::AnyInvocable<void(Port*)> callback);
  void SubscribePortComplete(const void* tag,
                             absl::AnyInvocable<void(Port*)> callback);
  void NotifyPortComplete(Port* port) {
    RTC_DCHECK_RUN_ON(thread_);
    port_complete_callback_list_.Send(this);
  }

  // This signal sent when port fails to allocate candidates and this port
  // can't be used in establishing the connections. When port is in shared mode
  // and port fails to allocate one of the candidates, port shouldn't send
  // this signal as other candidates might be usefull in establishing the
  // connection.
  [[deprecated("Use SubscribePortError(const void* tag, ...)")]]
  void SubscribePortError(absl::AnyInvocable<void(Port*)> callback);
  void SubscribePortError(const void* tag,
                          absl::AnyInvocable<void(Port*)> callback);
  void NotifyPortError(Port* port) {
    RTC_DCHECK_RUN_ON(thread_);
    port_error_callback_list_.Send(this);
  }

  [[deprecated("Use SubscribePortDestroyed(const void* tag, ...)")]]
  void SubscribePortDestroyed(
      std::function<void(PortInterface*)> callback) override;
  void SubscribePortDestroyed(
      const void* tag,
      std::function<void(PortInterface*)> callback) override;
  void SendPortDestroyed(Port* port);
  // Returns a map containing all of the connections of this port, keyed by the
  // remote address.
  typedef std::map<SocketAddress, Connection*> AddressMap;
  const AddressMap& connections() { return connections_; }

  // Returns the connection to the given address or NULL if none exists.
  Connection* GetConnection(const SocketAddress& remote_addr) override;

  // Removes and deletes a connection object. `DestroyConnection` will
  // delete the connection object directly whereas `DestroyConnectionAsync`
  // defers the `delete` operation to when the call stack has been unwound.
  // Async may be needed when deleting a connection object from within a
  // callback.
  void DestroyConnection(Connection* conn) override {
    DestroyConnectionInternal(conn, false);
  }

  void DestroyConnectionAsync(Connection* conn) override {
    DestroyConnectionInternal(conn, true);
  }

  // In a shared socket mode each port which shares the socket will decide
  // to accept the packet based on the `remote_addr`. Currently only UDP
  // port implemented this method.
  // TODO(mallinath) - Make it pure virtual.
  virtual bool HandleIncomingPacket(AsyncPacketSocket* socket,
                                    const ReceivedIpPacket& packet);

  // Shall the port handle packet from this `remote_addr`.
  // This method is overridden by TurnPort.
  virtual bool CanHandleIncomingPacketsFrom(
      const SocketAddress& remote_addr) const;

  // Sends a response error to the given request.
  void SendBindingErrorResponse(StunMessage* message,
                                const SocketAddress& addr,
                                int error_code,
                                absl::string_view reason) override;
  void SendUnknownAttributesErrorResponse(
      StunMessage* message,
      const SocketAddress& addr,
      const std::vector<uint16_t>& unknown_types);

  void EnablePortPackets() override;

  // Called if the port has no connections and is no longer useful.
  void Destroy();

  // Debugging description of this port
  std::string ToString() const override;
  uint16_t min_port() {
    RTC_DCHECK_RUN_ON(thread_);
    return min_port_;
  }
  uint16_t max_port() {
    RTC_DCHECK_RUN_ON(thread_);
    return max_port_;
  }

  // Timeout shortening function to speed up unit tests.
  void set_timeout_delay(int delay);

  // This method will return local and remote username fragments from the
  // stun username attribute if present.
  bool ParseStunUsername(const StunMessage* stun_msg,
                         std::string* local_username,
                         std::string* remote_username) const override;
  std::string CreateStunUsername(
      absl::string_view remote_username) const override;

  bool MaybeIceRoleConflict(const SocketAddress& addr,
                            IceMessage* stun_msg,
                            absl::string_view remote_ufrag) override;

  // Called when a packet has been sent to the socket.
  // This is made pure virtual to notify subclasses of Port that they MUST
  // listen to AsyncPacketSocket::SignalSentPacket and then call
  // PortInterface::OnSentPacket.
  virtual void OnSentPacket(AsyncPacketSocket* socket,
                            const SentPacketInfo& sent_packet) = 0;

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

  // Called when the Connection discovers a local peer reflexive candidate.
  void AddPrflxCandidate(const Candidate& local) override;

  int16_t network_cost() const override {
    RTC_DCHECK_RUN_ON(thread_);
    return network_cost_;
  }

  void GetStunStats(std::optional<StunStats>* /* stats */) override {}

  // Signals for ICE role conflicts.
  void SubscribeRoleConflict(absl::AnyInvocable<void()> callback) override;
  void NotifyRoleConflict() override;

  [[deprecated("Use SubscribeUnknownAddress(const void* tag, ...)")]]
  void SubscribeUnknownAddress(
      absl::AnyInvocable<void(PortInterface*,
                              const SocketAddress&,
                              ProtocolType,
                              IceMessage*,
                              const std::string&,
                              bool)> callback) override;
  void SubscribeUnknownAddress(
      const void* tag,
      absl::AnyInvocable<void(PortInterface*,
                              const SocketAddress&,
                              ProtocolType,
                              IceMessage*,
                              const std::string&,
                              bool)> callback) override;
  void NotifyUnknownAddress(PortInterface* port,
                            const SocketAddress& address,
                            ProtocolType proto,
                            IceMessage* msg,
                            const std::string& rf,
                            bool port_muxed) override;

  // This function causes strange linker behavior if it's inlined,
  // otherwise it would have been ABSL_DEPRECATE_AND_INLINE.
  [[deprecated("Use tagged version with span")]] void SubscribeReadPacket(
      absl::AnyInvocable<
          void(PortInterface*, const char*, size_t, const SocketAddress&)>
          callback) override;

  void SubscribeReadPacket(
      const void* tag,
      absl::AnyInvocable<void(PortInterface*,
                              std::span<const uint8_t>,
                              const SocketAddress&)> callback) override;

  void NotifyReadPacket(PortInterface* prot,
                        std::span<const uint8_t> data,
                        const SocketAddress& remote_address) override;

  [[deprecated("Use SubscribeSentPacket(const void* tag, ...)")]]
  void SubscribeSentPacket(
      absl::AnyInvocable<void(const SentPacketInfo&)> callback) override;
  void SubscribeSentPacket(
      const void* tag,
      absl::AnyInvocable<void(const SentPacketInfo&)> callback) override;
  void NotifySentPacket(const SentPacketInfo& packet) override;

 protected:
  void UpdateNetworkCost() override;

  WeakPtr<Port> NewWeakPtr() {
    RTC_DCHECK_RUN_ON(thread_);
    return weak_factory_.GetWeakPtr();
  }

  void AddAddress(const SocketAddress& address,
                  const SocketAddress& base_address,
                  const SocketAddress& related_address,
                  absl::string_view protocol,
                  absl::string_view relay_protocol,
                  absl::string_view tcptype,
                  IceCandidateType type,
                  uint32_t type_preference,
                  uint32_t relay_preference,
                  absl::string_view url,
                  bool is_final);

  void FinishAddingAddress(const Candidate& c, bool is_final)
      RTC_RUN_ON(thread_);

  virtual void PostAddAddress(bool is_final);

  // Adds the given connection to the map keyed by the remote candidate address.
  // If an existing connection has the same address, the existing one will be
  // replaced and destroyed.
  void AddOrReplaceConnection(Connection* conn);

  // Called when a packet is received from an unknown address that is not
  // currently a connection.  If this is an authenticated STUN binding request,
  // then we will signal the client.
  void OnReadPacket(const ReceivedIpPacket& packet, ProtocolType proto);

  // If the given data comprises a complete and correct STUN message then the
  // return value is true, otherwise false. If the message username corresponds
  // with this port's username fragment, msg will contain the parsed STUN
  // message.  Otherwise, the function may send a STUN response internally.
  // remote_username contains the remote fragment of the STUN username.
  bool GetStunMessage(std::span<const uint8_t> data,
                      const SocketAddress& addr,
                      std::unique_ptr<IceMessage>* out_msg,
                      std::string* out_username) override;
  // Checks if the address in addr is compatible with the port's ip.
  bool IsCompatibleAddress(const SocketAddress& addr);

  // Returns DSCP value packets generated by the port itself should use.
  DiffServCodePoint StunDscpValue() const override;

  // Extra work to be done in subclasses when a connection is destroyed.
  virtual void HandleConnectionDestroyed(Connection* /* conn */) {}

  void DestroyAllConnections();

  void CopyPortInformationToPacketInfo(PacketInfo* info) const;

  MdnsNameRegistrationStatus mdns_name_registration_status() const {
    RTC_DCHECK_RUN_ON(thread_);

    return mdns_name_registration_status_;
  }
  void set_mdns_name_registration_status(MdnsNameRegistrationStatus status) {
    RTC_DCHECK_RUN_ON(thread_);
    mdns_name_registration_status_ = status;
  }

  const Environment& env() const { return env_; }
  IceCandidateType type() const { return type_; }

  // Requests the Local Network Access Permission if necessary. Asynchronously
  // calls `callback` with the result of requesting the permission. If the
  // permission is not needed e.g. because `address` is public, it calls
  // `callback` synchronously. It's guaranteed that the callback won't be called
  // after this class is destroyed.
  void MaybeRequestLocalNetworkAccessPermission(
      const SocketAddress& address,
      absl::AnyInvocable<void(LocalNetworkAccessPermissionStatus)> callback);

 private:
  bool MaybeObfuscateAddress(const Candidate& c, bool is_final)
      RTC_RUN_ON(thread_);

  void PostDestroyIfDead(bool delayed);
  void DestroyIfDead();

  // Called internally when deleting a connection object.
  // Returns true if the connection object was removed from the `connections_`
  // list and the state updated accordingly. If the connection was not found
  // in the list, the return value is false. Note that this may indicate
  // incorrect behavior of external code that might be attempting to delete
  // connection objects from within a 'on destroyed' callback notification
  // for the connection object itself.
  bool OnConnectionDestroyed(Connection* conn);

  // Private implementation of DestroyConnection to keep the async usage
  // distinct.
  void DestroyConnectionInternal(Connection* conn, bool async);

  void OnNetworkTypeChanged(const ::webrtc::Network* network);

  void OnNetworkSliceChanged(const ::webrtc::Network* network);

  void OnRequestLocalNetworkAccessPermission(
      LocalNetworkAccessPermissionInterface* permission_query,
      absl::AnyInvocable<void(LocalNetworkAccessPermissionStatus)> callback,
      LocalNetworkAccessPermissionStatus status);

  void SendCandidateReadyCallbackList(Port*, const Candidate&);
  void SendPortCompleteCallbackList(Port*);
  void SendPortErrorCallbackList(Port*);

  const Environment env_;
  TaskQueueBase* const thread_;
  PacketSocketFactory* const factory_;
  LocalNetworkAccessPermissionFactoryInterface* const lna_permission_factory_;
  const IceCandidateType type_;
  bool send_retransmit_count_attribute_ RTC_GUARDED_BY(thread_);
  const ::webrtc::Network* network_;
  uint16_t min_port_ RTC_GUARDED_BY(thread_);
  uint16_t max_port_ RTC_GUARDED_BY(thread_);
  std::string content_name_ RTC_GUARDED_BY(thread_);
  int component_ RTC_GUARDED_BY(thread_);
  uint32_t generation_ RTC_GUARDED_BY(thread_);
  // In order to establish a connection to this Port (so that real data can be
  // sent through), the other side must send us a STUN binding request that is
  // authenticated with this username_fragment and password.
  // PortAllocatorSession will provide these username_fragment and password.
  std::string ice_username_fragment_ RTC_GUARDED_BY(thread_);
  std::string password_ RTC_GUARDED_BY(thread_);
  std::vector<Candidate> candidates_ RTC_GUARDED_BY(thread_);
  AddressMap connections_ RTC_GUARDED_BY(thread_);
  int timeout_delay_ RTC_GUARDED_BY(thread_);
  bool enable_port_packets_ RTC_GUARDED_BY(thread_);
  IceRole ice_role_ RTC_GUARDED_BY(thread_);
  uint64_t tiebreaker_ RTC_GUARDED_BY(thread_);
  bool shared_socket_ RTC_GUARDED_BY(thread_);

  // A virtual cost perceived by the user, usually based on the network type
  // (WiFi. vs. Cellular). It takes precedence over the priority when
  // comparing two connections.
  int16_t network_cost_ RTC_GUARDED_BY(thread_);
  // INIT: The state when a port is just created.
  // KEEP_ALIVE_UNTIL_PRUNED: A port should not be destroyed even if no
  // connection is using it.
  // PRUNED: It will be destroyed if no connection is using it for a period of
  // 30 seconds.
  enum class State { INIT, KEEP_ALIVE_UNTIL_PRUNED, PRUNED };
  State state_ RTC_GUARDED_BY(thread_) = State::INIT;
  int64_t last_time_all_connections_removed_ RTC_GUARDED_BY(thread_) = 0;
  MdnsNameRegistrationStatus mdns_name_registration_status_
      RTC_GUARDED_BY(thread_) = MdnsNameRegistrationStatus::kNotStarted;

  std::vector<std::unique_ptr<LocalNetworkAccessPermissionInterface>>
      permission_queries_ RTC_GUARDED_BY(thread_);

  CallbackList<PortInterface*,
               const SocketAddress&,
               ProtocolType,
               IceMessage*,
               const std::string&,
               bool>
      unknown_address_callbacks_;
  CallbackList<PortInterface*, std::span<const uint8_t>, const SocketAddress&>
      read_packet_callbacks_;
  CallbackList<const SentPacketInfo&> sent_packet_callbacks_;

  CallbackList<PortInterface*> port_destroyed_callback_list_
      RTC_GUARDED_BY(thread_);
  CallbackList<Port*, const IceCandidateErrorEvent&>
      candidate_error_callback_list_ RTC_GUARDED_BY(thread_);
  CallbackList<Port*, const Candidate&> candidate_ready_callback_list_
      RTC_GUARDED_BY(thread_);
  CallbackList<Port*> port_complete_callback_list_ RTC_GUARDED_BY(thread_);
  CallbackList<Port*> port_error_callback_list_ RTC_GUARDED_BY(thread_);

  absl::AnyInvocable<void()> role_conflict_callback_ RTC_GUARDED_BY(thread_);

  // Keep as the last member variable.
  WeakPtrFactory<Port> weak_factory_ RTC_GUARDED_BY(thread_);
};

}  //  namespace webrtc


#endif  // P2P_BASE_PORT_H_
