/*
 *  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 RTC_BASE_ASYNC_PACKET_SOCKET_H_
#define RTC_BASE_ASYNC_PACKET_SOCKET_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <span>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "api/sequence_checker.h"
#include "rtc_base/callback_list.h"
#include "rtc_base/dscp.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/network/sent_packet.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/system/rtc_export.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

// This structure holds the info needed to update the packet send time header
// extension, including the information needed to update the authentication tag
// after changing the value.
struct PacketTimeUpdateParams {
  PacketTimeUpdateParams();
  PacketTimeUpdateParams(const PacketTimeUpdateParams& other);
  ~PacketTimeUpdateParams();

  int rtp_sendtime_extension_id = -1;  // extension header id present in packet.
  std::vector<char> srtp_auth_key;     // Authentication key.
  int srtp_auth_tag_len = -1;          // Authentication tag length.
  int64_t srtp_packet_index = -1;  // Required for Rtp Packet authentication.
};

// This structure holds meta information for the packet which is about to send
// over network.
struct RTC_EXPORT AsyncSocketPacketOptions {
  AsyncSocketPacketOptions();
  explicit AsyncSocketPacketOptions(DiffServCodePoint dscp);
  AsyncSocketPacketOptions(const AsyncSocketPacketOptions& other);
  ~AsyncSocketPacketOptions();

  DiffServCodePoint dscp = DSCP_NO_CHANGE;

  // Packet will be sent with ECT(1), RFC-3168, Section 5.
  // Intended to be used with L4S
  // https://www.rfc-editor.org/rfc/rfc9331.html
  bool ect_1 = false;

  // When used with RTP packets (for example, PacketOptions), the value
  // should be 16 bits. A value of -1 represents "not set".
  int64_t packet_id = -1;
  PacketTimeUpdateParams packet_time_params;
  // PacketInfo is passed to SentPacket when signaling this packet is sent.
  PacketInfo info_signaled_after_sent;
  // True if this is a batchable packet. Batchable packets are collected at low
  // levels and sent first when their AsyncPacketSocket receives a
  // OnSendBatchComplete call.
  bool batchable = false;
  // True if this is the last packet of a batch.
  bool last_packet_in_batch = false;
};

// Provides the ability to receive packets asynchronously. Sends are not
// buffered since it is acceptable to drop packets under high load.
class RTC_EXPORT AsyncPacketSocket {
 public:
  enum State {
    STATE_CLOSED,
    STATE_BINDING,
    STATE_BOUND,
    STATE_CONNECTING,
    STATE_CONNECTED
  };

  AsyncPacketSocket() = default;
  virtual ~AsyncPacketSocket();

  AsyncPacketSocket(const AsyncPacketSocket&) = delete;
  AsyncPacketSocket& operator=(const AsyncPacketSocket&) = delete;

  // Returns current local address. Address may be set to null if the
  // socket is not bound yet (GetState() returns STATE_BINDING).
  virtual SocketAddress GetLocalAddress() const = 0;

  // Returns remote address. Returns zeroes if this is not a client TCP socket.
  virtual SocketAddress GetRemoteAddress() const = 0;

  // Send a packet.
  virtual int Send(const void* pv,
                   size_t cb,
                   const AsyncSocketPacketOptions& options) = 0;
  int Send(std::span<const uint8_t> data,
           const AsyncSocketPacketOptions& options) {
    return Send(data.data(), data.size(), options);
  }
  virtual int SendTo(const void* pv,
                     size_t cb,
                     const SocketAddress& addr,
                     const AsyncSocketPacketOptions& options) = 0;
  int SendTo(std::span<const uint8_t> data,
             const SocketAddress& addr,
             const AsyncSocketPacketOptions& options) {
    return SendTo(data.data(), data.size(), addr, options);
  }

  // Close the socket.
  virtual int Close() = 0;

  // Returns current state of the socket.
  virtual State GetState() const = 0;

  // Get/set options.
  virtual int GetOption(Socket::Option opt, int* value) = 0;
  virtual int SetOption(Socket::Option opt, int value) = 0;

  // Get/Set current error.
  // TODO: Remove SetError().
  virtual int GetError() const = 0;
  virtual void SetError(int error) = 0;

  // Register a callback to be called when the socket is closed.
  void SubscribeCloseEvent(
      const void* removal_tag,
      std::function<void(AsyncPacketSocket*, int)> callback);
  void UnsubscribeCloseEvent(const void* removal_tag);

  void RegisterReceivedPacketCallback(
      absl::AnyInvocable<void(AsyncPacketSocket*, const ReceivedIpPacket&)>
          received_packet_callback);
  void DeregisterReceivedPacketCallback();

  // Emitted each time a packet is sent.
  void SubscribeSentPacket(
      void* tag,
      absl::AnyInvocable<void(AsyncPacketSocket*, const SentPacketInfo&)>
          callback);
  void UnsubscribeSentPacket(void* tag) {
    sent_packet_callbacks_.RemoveReceivers(tag);
  }
  void NotifySentPacket(AsyncPacketSocket* socket, const SentPacketInfo& info) {
    sent_packet_callbacks_.Send(socket, info);
  }

  // Emitted when the socket is currently able to send.
  void SubscribeReadyToSend(
      void* tag,
      absl::AnyInvocable<void(AsyncPacketSocket*)> callback) {
    ready_to_send_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void UnsubscribeReadyToSend(void* tag) {
    ready_to_send_callbacks_.RemoveReceivers(tag);
  }
  void NotifyReadyToSend(AsyncPacketSocket* socket) {
    ready_to_send_callbacks_.Send(socket);
  }

  // Emitted after address for the socket is allocated, i.e. binding
  // is finished. State of the socket is changed from BINDING to BOUND
  // (for UDP sockets).
  void SubscribeAddressReady(
      void* tag,
      absl::AnyInvocable<void(AsyncPacketSocket*, const SocketAddress&)>
          callback) {
    address_ready_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void UnsubscribeAddressReady(void* tag) {
    address_ready_callbacks_.RemoveReceivers(tag);
  }
  void NotifyAddressReady(AsyncPacketSocket* socket,
                          const SocketAddress& address) {
    address_ready_callbacks_.Send(socket, address);
  }

  // Emitted for client TCP sockets when state is changed from
  // CONNECTING to CONNECTED.
  void NotifyConnect(AsyncPacketSocket* socket) {
    connect_callbacks_.Send(socket);
  }

  void SubscribeConnect(void* tag,
                        absl::AnyInvocable<void(AsyncPacketSocket*)> callback) {
    connect_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void UnsubscribeConnect(void* tag) {
    connect_callbacks_.RemoveReceivers(tag);
  }

  void NotifyClosedForTest(int err) { NotifyClosed(err); }

 protected:
  void NotifyClosed(int err) {
    RTC_DCHECK_RUN_ON(&network_checker_);
    on_close_.Send(this, err);
  }

  void NotifyPacketReceived(const ReceivedIpPacket& packet);

  RTC_NO_UNIQUE_ADDRESS SequenceChecker network_checker_{
      SequenceChecker::kDetached};

 private:
  CallbackList<AsyncPacketSocket*, int> on_close_
      RTC_GUARDED_BY(&network_checker_);
  absl::AnyInvocable<void(AsyncPacketSocket*, const ReceivedIpPacket&)>
      received_packet_callback_ RTC_GUARDED_BY(&network_checker_);
  CallbackList<AsyncPacketSocket*> connect_callbacks_;
  CallbackList<AsyncPacketSocket*, const SentPacketInfo&>
      sent_packet_callbacks_;
  CallbackList<AsyncPacketSocket*> ready_to_send_callbacks_;
  CallbackList<AsyncPacketSocket*, const SocketAddress&>
      address_ready_callbacks_;
};

// Listen socket, producing an AsyncPacketSocket when a peer connects.
class RTC_EXPORT AsyncListenSocket {
 public:
  enum class State {
    kClosed,
    kBound,
  };

  AsyncListenSocket() = default;
  virtual ~AsyncListenSocket() = default;

  // Returns current state of the socket.
  virtual State GetState() const = 0;

  // Returns current local address. Address may be set to null if the
  // socket is not bound yet (GetState() returns kBinding).
  virtual SocketAddress GetLocalAddress() const = 0;

  void SubscribeNewConnection(
      void* tag,
      absl::AnyInvocable<void(AsyncListenSocket*, AsyncPacketSocket*)>
          callback) {
    new_connection_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void UnsubscribeNewConnection(void* tag) {
    new_connection_callbacks_.RemoveReceivers(tag);
  }
  void NotifyNewConnection(AsyncListenSocket* listen_socket,
                           AsyncPacketSocket* packet_socket) {
    new_connection_callbacks_.Send(listen_socket, packet_socket);
  }

 private:
  CallbackList<AsyncListenSocket*, AsyncPacketSocket*>
      new_connection_callbacks_;
};

void CopySocketInformationToPacketInfo(size_t packet_size_bytes,
                                       const AsyncPacketSocket& socket_from,
                                       PacketInfo* info);

}  //  namespace webrtc

#endif  // RTC_BASE_ASYNC_PACKET_SOCKET_H_
