/*
 *  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 <cstdint>
#include <memory>
#include <string>
#include <utility>

#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/sequence_checker.h"
#include "net/dcsctp/packet/chunk/abort_chunk.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/chunk/cookie_ack_chunk.h"
#include "net/dcsctp/packet/chunk/cookie_echo_chunk.h"
#include "net/dcsctp/packet/chunk/data_chunk.h"
#include "net/dcsctp/packet/chunk/data_common.h"
#include "net/dcsctp/packet/chunk/error_chunk.h"
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
#include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h"
#include "net/dcsctp/packet/chunk/heartbeat_request_chunk.h"
#include "net/dcsctp/packet/chunk/idata_chunk.h"
#include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h"
#include "net/dcsctp/packet/chunk/init_ack_chunk.h"
#include "net/dcsctp/packet/chunk/init_chunk.h"
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
#include "net/dcsctp/packet/chunk/sack_chunk.h"
#include "net/dcsctp/packet/chunk/shutdown_ack_chunk.h"
#include "net/dcsctp/packet/chunk/shutdown_chunk.h"
#include "net/dcsctp/packet/chunk/shutdown_complete_chunk.h"
#include "net/dcsctp/packet/data.h"
#include "net/dcsctp/packet/sctp_packet.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/rx/data_tracker.h"
#include "net/dcsctp/rx/reassembly_queue.h"
#include "net/dcsctp/socket/callback_deferrer.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/retransmission_error_counter.h"
#include "net/dcsctp/tx/retransmission_queue.h"
#include "net/dcsctp/tx/retransmission_timeout.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(rtc::ArrayView<const uint8_t> data) override;
  void HandleTimeout(TimeoutID timeout_id) override;
  void Connect() override;
  void RestoreFromState(const DcSctpSocketHandoverState& state) override;
  void Shutdown() override;
  void Close() override;
  SendStatus Send(DcSctpMessage message,
                  const SendOptions& send_options) override;
  ResetStreamsStatus ResetStreams(
      rtc::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;
  absl::optional<Metrics> GetMetrics() const override;
  HandoverReadinessStatus GetHandoverReadiness() const override;
  absl::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);
  };

  // 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);
  // Fills in `connect_params` with random verification tag and initial TSN.
  void MakeConnectionParameters();
  // 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
  absl::optional<DurationMs> OnInitTimerExpiry();
  absl::optional<DurationMs> OnCookieTimerExpiry();
  absl::optional<DurationMs> OnShutdownTimerExpiry();
  void OnSentPacket(rtc::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();
  // 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(rtc::ArrayView<const uint8_t> payload);
  // Called whenever there may be reassembled messages, and delivers those.
  void DeliverReassembledMessages();
  // 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 absl::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_;
  RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker thread_checker_;
  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_
