/*
 *  Copyright (c) 2021 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 NET_DCSCTP_SOCKET_DCSCTP_SOCKET_H_
#define NET_DCSCTP_SOCKET_DCSCTP_SOCKET_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/units/time_delta.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/chunk/data_common.h"
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
#include "net/dcsctp/packet/sctp_packet.h"
#include "net/dcsctp/public/dcsctp_handover_state.h"
#include "net/dcsctp/public/dcsctp_message.h"
#include "net/dcsctp/public/dcsctp_options.h"
#include "net/dcsctp/public/dcsctp_socket.h"
#include "net/dcsctp/public/packet_observer.h"
#include "net/dcsctp/public/types.h"
#include "net/dcsctp/socket/callback_deferrer.h"
#include "net/dcsctp/socket/capabilities.h"
#include "net/dcsctp/socket/packet_sender.h"
#include "net/dcsctp/socket/state_cookie.h"
#include "net/dcsctp/socket/transmission_control_block.h"
#include "net/dcsctp/timer/timer.h"
#include "net/dcsctp/tx/rr_send_queue.h"

namespace dcsctp {

// DcSctpSocket represents a single SCTP socket, to be used over DTLS.
//
// Every dcSCTP is completely isolated from any other socket.
//
// This class manages all packet and chunk dispatching and mainly handles the
// connection sequences (connect, close, shutdown, etc) as well as managing
// the Transmission Control Block (tcb).
//
// This class is thread-compatible.
class DcSctpSocket : public DcSctpSocketInterface {
 public:
  // Instantiates a DcSctpSocket, which interacts with the world through the
  // `callbacks` interface and is configured using `options`.
  //
  // For debugging, `log_prefix` will prefix all debug logs, and a
  // `packet_observer` can be attached to e.g. dump sent and received packets.
  DcSctpSocket(absl::string_view log_prefix,
               DcSctpSocketCallbacks& callbacks,
               std::unique_ptr<PacketObserver> packet_observer,
               const DcSctpOptions& options);

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

  // Implementation of `DcSctpSocketInterface`.
  void ReceivePacket(webrtc::ArrayView<const uint8_t> data) override;
  size_t MessagesReady() const override;
  std::optional<DcSctpMessage> GetNextMessage() override;
  void HandleTimeout(TimeoutID timeout_id) override;
  void Connect() override;
  static std::vector<uint8_t> GenerateConnectionToken(
      const DcSctpOptions& options,
      std::function<uint32_t(uint32_t low, uint32_t high)> get_random_uint32);
  bool ConnectWithConnectionToken(
      webrtc::ArrayView<const uint8_t> my_data,
      webrtc::ArrayView<const uint8_t> peer_data) override;

  void RestoreFromState(const DcSctpSocketHandoverState& state) override;
  void Shutdown() override;
  void Close() override;
  SendStatus Send(DcSctpMessage message,
                  const SendOptions& send_options) override;
  std::vector<SendStatus> SendMany(webrtc::ArrayView<DcSctpMessage> messages,
                                   const SendOptions& send_options) override;
  ResetStreamsStatus ResetStreams(
      webrtc::ArrayView<const StreamID> outgoing_streams) override;
  SocketState state() const override;
  const DcSctpOptions& options() const override { return options_; }
  void SetMaxMessageSize(size_t max_message_size) override;
  void SetStreamPriority(StreamID stream_id, StreamPriority priority) override;
  StreamPriority GetStreamPriority(StreamID stream_id) const override;
  size_t buffered_amount(StreamID stream_id) const override;
  size_t buffered_amount_low_threshold(StreamID stream_id) const override;
  void SetBufferedAmountLowThreshold(StreamID stream_id, size_t bytes) override;
  std::optional<Metrics> GetMetrics() const override;
  HandoverReadinessStatus GetHandoverReadiness() const override;
  std::optional<DcSctpSocketHandoverState> GetHandoverStateAndClose() override;
  SctpImplementation peer_implementation() const override {
    return metrics_.peer_implementation;
  }
  // Returns this socket's verification tag, or zero if not yet connected.
  VerificationTag verification_tag() const {
    return tcb_ != nullptr ? tcb_->my_verification_tag() : VerificationTag(0);
  }

 private:
  // Parameter proposals valid during the connect phase.
  struct ConnectParameters {
    TSN initial_tsn = TSN(0);
    VerificationTag verification_tag = VerificationTag(0);
    bool is_out_of_bands_connect = false;
  };

  // Detailed state (separate from SocketState, which is the public state).
  enum class State {
    kClosed,
    kCookieWait,
    // TCB valid in these:
    kCookieEchoed,
    kEstablished,
    kShutdownPending,
    kShutdownSent,
    kShutdownReceived,
    kShutdownAckSent,
  };

  // Returns the log prefix used for debug logging.
  std::string log_prefix() const;

  bool IsConsistent() const;
  static constexpr absl::string_view ToString(DcSctpSocket::State state);

  void CreateTransmissionControlBlock(const Capabilities& capabilities,
                                      VerificationTag my_verification_tag,
                                      TSN my_initial_tsn,
                                      VerificationTag peer_verification_tag,
                                      TSN peer_initial_tsn,
                                      size_t a_rwnd,
                                      TieTag tie_tag);

  // Changes the socket state, given a `reason` (for debugging/logging).
  void SetState(State state, absl::string_view reason);
  // Closes the association. Note that the TCB will not be valid past this call.
  void InternalClose(ErrorKind error, absl::string_view message);
  // Closes the association, because of too many retransmission errors.
  void CloseConnectionBecauseOfTooManyTransmissionErrors();
  // Timer expiration handlers
  webrtc::TimeDelta OnInitTimerExpiry();
  webrtc::TimeDelta OnCookieTimerExpiry();
  webrtc::TimeDelta OnShutdownTimerExpiry();
  void OnSentPacket(webrtc::ArrayView<const uint8_t> packet,
                    SendPacketStatus status);
  // Sends SHUTDOWN or SHUTDOWN-ACK if the socket is shutting down and if all
  // outstanding data has been acknowledged.
  void MaybeSendShutdownOrAck();
  // If the socket is shutting down, responds SHUTDOWN to any incoming DATA.
  void MaybeSendShutdownOnPacketReceived(const SctpPacket& packet);
  // If there are streams pending to be reset, send a request to reset them.
  void MaybeSendResetStreamsRequest();
  // Performs internal processing shared between Send and SendMany.
  SendStatus InternalSend(const DcSctpMessage& message,
                          const SendOptions& send_options);
  // Sends a INIT chunk.
  void SendInit();
  // Sends a SHUTDOWN chunk.
  void SendShutdown();
  // Sends a SHUTDOWN-ACK chunk.
  void SendShutdownAck();
  // Validates the SCTP packet, as a whole - not the validity of individual
  // chunks within it, as that's done in the different chunk handlers.
  bool ValidatePacket(const SctpPacket& packet);
  // Parses `payload`, which is a serialized packet that is just going to be
  // sent and prints all chunks.
  void DebugPrintOutgoing(webrtc::ArrayView<const uint8_t> payload);
  // Called whenever data has been received, or the cumulative acknowledgment
  // TSN has moved, that may result in delivering messages.
  void MaybeDeliverMessages();
  // Returns true if there is a TCB, and false otherwise (and reports an error).
  bool ValidateHasTCB();

  // Returns true if the parsing of a chunk of type `T` succeeded. If it didn't,
  // it reports an error and returns false.
  template <class T>
  bool ValidateParseSuccess(const std::optional<T>& c) {
    if (c.has_value()) {
      return true;
    }

    ReportFailedToParseChunk(T::kType);
    return false;
  }

  // Reports failing to have parsed a chunk with the provided `chunk_type`.
  void ReportFailedToParseChunk(int chunk_type);
  // Called when unknown chunks are received. May report an error.
  bool HandleUnrecognizedChunk(const SctpPacket::ChunkDescriptor& descriptor);

  // Will dispatch more specific chunk handlers.
  bool Dispatch(const CommonHeader& header,
                const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming DATA chunks.
  void HandleData(const CommonHeader& header,
                  const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming I-DATA chunks.
  void HandleIData(const CommonHeader& header,
                   const SctpPacket::ChunkDescriptor& descriptor);
  // Common handler for DATA and I-DATA chunks.
  void HandleDataCommon(AnyDataChunk& chunk);
  // Handles incoming INIT chunks.
  void HandleInit(const CommonHeader& header,
                  const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming INIT-ACK chunks.
  void HandleInitAck(const CommonHeader& header,
                     const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming SACK chunks.
  void HandleSack(const CommonHeader& header,
                  const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming HEARTBEAT chunks.
  void HandleHeartbeatRequest(const CommonHeader& header,
                              const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming HEARTBEAT-ACK chunks.
  void HandleHeartbeatAck(const CommonHeader& header,
                          const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming ABORT chunks.
  void HandleAbort(const CommonHeader& header,
                   const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming ERROR chunks.
  void HandleError(const CommonHeader& header,
                   const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming COOKIE-ECHO chunks.
  void HandleCookieEcho(const CommonHeader& header,
                        const SctpPacket::ChunkDescriptor& descriptor);
  // Handles receiving COOKIE-ECHO when there already is a TCB. The return value
  // indicates if the processing should continue.
  bool HandleCookieEchoWithTCB(const CommonHeader& header,
                               const StateCookie& cookie);
  // Handles incoming COOKIE-ACK chunks.
  void HandleCookieAck(const CommonHeader& header,
                       const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming SHUTDOWN chunks.
  void HandleShutdown(const CommonHeader& header,
                      const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming SHUTDOWN-ACK chunks.
  void HandleShutdownAck(const CommonHeader& header,
                         const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming FORWARD-TSN chunks.
  void HandleForwardTsn(const CommonHeader& header,
                        const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming I-FORWARD-TSN chunks.
  void HandleIForwardTsn(const CommonHeader& header,
                         const SctpPacket::ChunkDescriptor& descriptor);
  // Handles incoming RE-CONFIG chunks.
  void HandleReconfig(const CommonHeader& header,
                      const SctpPacket::ChunkDescriptor& descriptor);
  // Common handled for FORWARD-TSN/I-FORWARD-TSN.
  void HandleForwardTsnCommon(const AnyForwardTsnChunk& chunk);
  // Handles incoming SHUTDOWN-COMPLETE chunks
  void HandleShutdownComplete(const CommonHeader& header,
                              const SctpPacket::ChunkDescriptor& descriptor);

  const std::string log_prefix_;
  const std::unique_ptr<PacketObserver> packet_observer_;
  Metrics metrics_;
  DcSctpOptions options_;

  // Enqueues callbacks and dispatches them just before returning to the caller.
  CallbackDeferrer callbacks_;

  TimerManager timer_manager_;
  const std::unique_ptr<Timer> t1_init_;
  const std::unique_ptr<Timer> t1_cookie_;
  const std::unique_ptr<Timer> t2_shutdown_;

  // Packets that failed to be sent, but should be retried.
  PacketSender packet_sender_;

  // The actual SendQueue implementation. As data can be sent on a socket before
  // the connection is established, this component is not in the TCB.
  RRSendQueue send_queue_;

  // Contains verification tag and initial TSN between having sent the INIT
  // until the connection is established (there is no TCB at this point).
  ConnectParameters connect_params_;
  // The socket state.
  State state_ = State::kClosed;
  // If the connection is established, contains a transmission control block.
  std::unique_ptr<TransmissionControlBlock> tcb_;
};
}  // namespace dcsctp

#endif  // NET_DCSCTP_SOCKET_DCSCTP_SOCKET_H_
