/*
 *  Copyright 2020 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 PC_SCTP_DATA_CHANNEL_H_
#define PC_SCTP_DATA_CHANNEL_H_

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

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/data_channel_interface.h"
#include "api/priority.h"
#include "api/rtc_error.h"
#include "api/scoped_refptr.h"
#include "api/sctp_transport_interface.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "api/transport/data_channel_transport_interface.h"
#include "pc/data_channel_utils.h"
#include "pc/sctp_utils.h"
#include "rtc_base/checks.h"
#include "rtc_base/containers/flat_set.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/ssl_stream_adapter.h"  // For SSLRole
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/weak_ptr.h"

namespace webrtc {

class SctpDataChannel;

// Interface that acts as a bridge from the data channel to the transport.
// All methods in this interface need to be invoked on the network thread.
class SctpDataChannelControllerInterface {
 public:
  // Sends the data to the transport.
  virtual RTCError SendData(StreamId sid,
                            const SendDataParams& params,
                            const CopyOnWriteBuffer& payload) = 0;
  // Adds the data channel SID to the transport for SCTP.
  virtual RTCError AddSctpDataStream(StreamId sid, PriorityValue priority) = 0;
  // Begins the closing procedure by sending an outgoing stream reset. Still
  // need to wait for callbacks to tell when this completes.
  virtual void RemoveSctpDataStream(StreamId sid) = 0;
  // Notifies the controller of state changes.
  virtual void OnChannelStateChanged(SctpDataChannel* data_channel,
                                     DataChannelInterface::DataState state) = 0;
  virtual size_t buffered_amount(StreamId sid) const = 0;
  virtual size_t buffered_amount_low_threshold(StreamId sid) const = 0;
  virtual void SetBufferedAmountLowThreshold(StreamId sid, size_t bytes) = 0;

 protected:
  virtual ~SctpDataChannelControllerInterface() {}
};

struct InternalDataChannelInit : public DataChannelInit {
  enum OpenHandshakeRole { kOpener, kAcker, kNone };
  // The default role is kOpener because the default `negotiated` is false.
  InternalDataChannelInit() : open_handshake_role(kOpener) {}
  explicit InternalDataChannelInit(const DataChannelInit& base);

  // Does basic validation to determine if a data channel instance can be
  // constructed using the configuration.
  bool IsValid() const;

  OpenHandshakeRole open_handshake_role;
  // Optional fallback or backup flag from PC that's used for non-prenegotiated
  // stream ids in situations where we cannot determine the SSL role from the
  // transport for purposes of generating a stream ID.
  // See: https://www.rfc-editor.org/rfc/rfc8832.html#name-protocol-overview
  std::optional<SSLRole> fallback_ssl_role;
};

// Helper class to allocate unique IDs for SCTP DataChannels.
class SctpSidAllocator {
 public:
  SctpSidAllocator() = default;
  void SetMaxSid(int max_sid) {
    RTC_DCHECK_RUN_ON(&sequence_checker_);
    RTC_DCHECK(max_sid >= 0 && max_sid <= max_sid_)
        << "max_sid can only be decreased, and can't be negative: changing from"
        << max_sid_ << " to " << max_sid;
    max_sid_ = max_sid;
  }
  // Gets the first unused odd/even id based on the DTLS role. If `role` is
  // SSL_CLIENT, the allocated id starts from 0 and takes even numbers;
  // otherwise, the id starts from 1 and takes odd numbers.
  // If a `StreamId` cannot be allocated, `std::nullopt` is returned.
  std::optional<StreamId> AllocateSid(SSLRole role);

  // Attempts to reserve a specific sid. Returns false if it's unavailable.
  bool ReserveSid(StreamId sid);

  // Indicates that `sid` isn't in use any more, and is thus available again.
  void ReleaseSid(StreamId sid);

 private:
  int max_sid_ RTC_GUARDED_BY(&sequence_checker_) = kMaxSctpSid;
  flat_set<StreamId> used_sids_ RTC_GUARDED_BY(&sequence_checker_);
  RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_{
      SequenceChecker::kDetached};
};

// SctpDataChannel is an implementation of the DataChannelInterface based on
// SctpTransport. It provides an implementation of unreliable or
// reliable data channels.

// DataChannel states:
// kConnecting: The channel has been created the transport might not yet be
//              ready.
// kOpen: The open handshake has been performed (if relevant) and the data
//        channel is able to send messages.
// kClosing: DataChannelInterface::Close has been called, or the remote side
//           initiated the closing procedure, but the closing procedure has not
//           yet finished.
// kClosed: The closing handshake is finished (possibly initiated from this,
//          side, possibly from the peer).
//
// How the closing procedure works for SCTP:
// 1. Alice calls Close(), state changes to kClosing.
// 2. Alice finishes sending any queued data.
// 3. Alice calls RemoveSctpDataStream, sends outgoing stream reset.
// 4. Bob receives incoming stream reset; OnClosingProcedureStartedRemotely
//    called.
// 5. Bob sends outgoing stream reset.
// 6. Alice receives incoming reset, Bob receives acknowledgement. Both receive
//    OnClosingProcedureComplete callback and transition to kClosed.
class SctpDataChannel : public DataChannelInterface {
 public:
  // The `controller_safety` flag is used for the ObserverAdapter callback proxy
  // which delivers callbacks on the `signaling_thread` but must not deliver
  // such callbacks after the peerconnection has been closed. The data
  // controller will update the flag when closed, which will cancel any pending
  // event notifications.
  static scoped_refptr<SctpDataChannel> Create(
      WeakPtr<SctpDataChannelControllerInterface> controller,
      absl::string_view label,
      bool connected_to_transport,
      const InternalDataChannelInit& config,
      scoped_refptr<PendingTaskSafetyFlag> controller_safety,
      Thread* signaling_thread,
      Thread* network_thread);

  // Instantiates an API proxy for a SctpDataChannel instance that will be
  // handed out to external callers.
  static scoped_refptr<DataChannelInterface> CreateProxy(
      scoped_refptr<SctpDataChannel> channel);

  void RegisterObserver(DataChannelObserver* observer) override;
  void UnregisterObserver() override;

  std::string label() const override;
  bool reliable() const override;
  bool ordered() const override;

  std::optional<int> maxPacketLifeTime() const override;
  std::optional<int> maxRetransmitsOpt() const override;
  std::string protocol() const override;
  bool negotiated() const override;
  int id() const override;
  PriorityValue priority() const override;

  uint64_t buffered_amount() const override;
  void Close() override;
  DataState state() const override;
  RTCError error() const override;
  uint32_t messages_sent() const override;
  uint64_t bytes_sent() const override;
  uint32_t messages_received() const override;
  uint64_t bytes_received() const override;
  bool Send(const DataBuffer& buffer) override;
  void SendAsync(DataBuffer buffer,
                 absl::AnyInvocable<void(RTCError) &&> on_complete) override;

  // Close immediately, ignoring any queued data or closing procedure.
  // This is called when the underlying SctpTransport is being destroyed.
  // It is also called by the PeerConnection if SCTP ID assignment fails.
  void CloseAbruptlyWithError(RTCError error);
  // Specializations of CloseAbruptlyWithError
  void CloseAbruptlyWithDataChannelFailure(const std::string& message);

  // Called when the SctpTransport's ready to use. That can happen when we've
  // finished negotiation, or if the channel was created after negotiation has
  // already finished.
  void OnTransportReady();

  void OnDataReceived(DataMessageType type, const CopyOnWriteBuffer& payload);

  // Sets the SCTP sid and adds to transport layer if not set yet. Should only
  // be called once.
  void SetSctpSid_n(StreamId sid);

  // The remote side started the closing procedure by resetting its outgoing
  // stream (our incoming stream). Sets state to kClosing.
  void OnClosingProcedureStartedRemotely();
  // The closing procedure is complete; both incoming and outgoing stream
  // resets are done and the channel can transition to kClosed. Called
  // asynchronously after RemoveSctpDataStream.
  void OnClosingProcedureComplete();
  // Called when the transport channel is created.
  void OnTransportChannelCreated();
  // Called when the transport channel is unusable.
  // This method makes sure the DataChannel is disconnected and changes state
  // to kClosed.
  void OnTransportChannelClosed(RTCError error);
  // Called when the amount of data buffered to be sent falls to or below the
  // threshold set when calling `SetBufferedAmountLowThreshold`.
  void OnBufferedAmountLow();
  // Called when the data channel's max-message-size has changed as a result
  // of SDP negotiation.
  void OnMaxMessageSize(int max_message_size);

  DataChannelStats GetStats() const;

  // Returns a unique identifier that's guaranteed to always be available,
  // doesn't change throughout SctpDataChannel's lifetime and is used for
  // stats purposes (see also `GetStats()`).
  int internal_id() const { return internal_id_; }

  std::optional<StreamId> sid_n() const {
    RTC_DCHECK_RUN_ON(network_thread_);
    return id_n_;
  }

  // Reset the allocator for internal ID values for testing, so that
  // the internal IDs generated are predictable. Test only.
  static void ResetInternalIdAllocatorForTesting(int new_value);

 protected:
  SctpDataChannel(const InternalDataChannelInit& config,
                  WeakPtr<SctpDataChannelControllerInterface> controller,
                  absl::string_view label,
                  bool connected_to_transport,
                  scoped_refptr<PendingTaskSafetyFlag> controller_safety,
                  Thread* signaling_thread,
                  Thread* network_thread);
  ~SctpDataChannel() override;

 private:
  class ObserverAdapter;

  // The OPEN(_ACK) signaling state.
  enum HandshakeState {
    kHandshakeInit,
    kHandshakeShouldSendOpen,
    kHandshakeShouldSendAck,
    kHandshakeWaitingForAck,
    kHandshakeReady
  };

  RTCError SendImpl(DataBuffer buffer) RTC_RUN_ON(network_thread_);
  void UpdateState() RTC_RUN_ON(network_thread_);
  void SetState(DataState state) RTC_RUN_ON(network_thread_);

  void DeliverQueuedReceivedData() RTC_RUN_ON(network_thread_);

  RTCError SendDataMessage(const DataBuffer& buffer, bool queue_if_blocked)
      RTC_RUN_ON(network_thread_);

  bool SendControlMessage(const CopyOnWriteBuffer& buffer)
      RTC_RUN_ON(network_thread_);

  bool connected_to_transport() const RTC_RUN_ON(network_thread_) {
    return connected_to_transport_;
  }
  void MaybeSendOnBufferedAmountChanged() RTC_RUN_ON(network_thread_);

  Thread* const signaling_thread_;
  Thread* const network_thread_;
  std::optional<StreamId> id_n_ RTC_GUARDED_BY(network_thread_) = std::nullopt;
  const int internal_id_;
  const std::string label_;
  const std::string protocol_;
  const std::optional<int> max_retransmit_time_;
  const std::optional<int> max_retransmits_;
  const std::optional<PriorityValue> priority_;
  const bool negotiated_;
  const bool ordered_;
  // See the body of `MaybeSendOnBufferedAmountChanged`.
  size_t expected_buffer_amount_ = 0;

  DataChannelObserver* observer_ RTC_GUARDED_BY(network_thread_) = nullptr;
  std::unique_ptr<ObserverAdapter> observer_adapter_;
  DataState state_ RTC_GUARDED_BY(network_thread_) = kConnecting;
  RTCError error_ RTC_GUARDED_BY(network_thread_);
  uint32_t messages_sent_ RTC_GUARDED_BY(network_thread_) = 0;
  uint64_t bytes_sent_ RTC_GUARDED_BY(network_thread_) = 0;
  uint32_t messages_received_ RTC_GUARDED_BY(network_thread_) = 0;
  uint64_t bytes_received_ RTC_GUARDED_BY(network_thread_) = 0;
  std::optional<int> max_message_size_ RTC_GUARDED_BY(network_thread_);
  WeakPtr<SctpDataChannelControllerInterface> controller_
      RTC_GUARDED_BY(network_thread_);
  HandshakeState handshake_state_ RTC_GUARDED_BY(network_thread_) =
      kHandshakeInit;
  // Did we already start the graceful SCTP closing procedure?
  bool started_closing_procedure_ RTC_GUARDED_BY(network_thread_) = false;
  bool connected_to_transport_ RTC_GUARDED_BY(network_thread_) = false;
  PacketQueue queued_received_data_ RTC_GUARDED_BY(network_thread_);
  scoped_refptr<PendingTaskSafetyFlag> controller_safety_;
};

}  // namespace webrtc

#endif  // PC_SCTP_DATA_CHANNEL_H_
