/*
 *  Copyright 2019 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_DATA_CHANNEL_CONTROLLER_H_
#define PC_DATA_CHANNEL_CONTROLLER_H_

#include <string>
#include <vector>

#include "api/data_channel_interface.h"
#include "api/priority.h"
#include "api/rtc_error.h"
#include "api/scoped_refptr.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_data_channel.h"
#include "rtc_base/checks.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/weak_ptr.h"

namespace webrtc {

class PeerConnectionInternal;

class DataChannelController : public SctpDataChannelControllerInterface,
                              public DataChannelSink {
 public:
  explicit DataChannelController(PeerConnectionInternal* pc) : pc_(pc) {}
  ~DataChannelController();

  // Not copyable or movable.
  DataChannelController(DataChannelController&) = delete;
  DataChannelController& operator=(const DataChannelController& other) = delete;
  DataChannelController(DataChannelController&&) = delete;
  DataChannelController& operator=(DataChannelController&& other) = delete;

  // Implements
  // SctpDataChannelProviderInterface.
  RTCError SendData(StreamId sid,
                    const SendDataParams& params,
                    const rtc::CopyOnWriteBuffer& payload) override;
  void AddSctpDataStream(StreamId sid, PriorityValue priority) override;
  void RemoveSctpDataStream(StreamId sid) override;
  void OnChannelStateChanged(SctpDataChannel* channel,
                             DataChannelInterface::DataState state) override;
  size_t buffered_amount(StreamId sid) const override;
  size_t buffered_amount_low_threshold(StreamId sid) const override;
  void SetBufferedAmountLowThreshold(StreamId sid, size_t bytes) override;

  // Implements DataChannelSink.
  void OnDataReceived(int channel_id,
                      DataMessageType type,
                      const rtc::CopyOnWriteBuffer& buffer) override;
  void OnChannelClosing(int channel_id) override;
  void OnChannelClosed(int channel_id) override;
  void OnReadyToSend() override;
  void OnTransportClosed(RTCError error) override;
  void OnBufferedAmountLow(int channel_id) override;

  // Called as part of destroying the owning PeerConnection.
  void PrepareForShutdown();

  // Called from PeerConnection::SetupDataChannelTransport_n
  void SetupDataChannelTransport_n(DataChannelTransportInterface* transport);
  // Called from PeerConnection::TeardownDataChannelTransport_n
  void TeardownDataChannelTransport_n(RTCError error);

  // Called from PeerConnection::OnTransportChanged
  // to make required changes to datachannels' transports.
  void OnTransportChanged(
      DataChannelTransportInterface* data_channel_transport);

  // Called from PeerConnection::GetDataChannelStats on the signaling thread.
  std::vector<DataChannelStats> GetDataChannelStats() const;

  // Creates channel and adds it to the collection of DataChannels that will
  // be offered in a SessionDescription, and wraps it in a proxy object.
  RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>
  InternalCreateDataChannelWithProxy(const std::string& label,
                                     const InternalDataChannelInit& config);
  void AllocateSctpSids(rtc::SSLRole role);

  // Check if data channels are currently tracked. Used to decide whether a
  // rejected m=application section should be reoffered.
  bool HasDataChannels() const;

  // At some point in time, a data channel has existed.
  bool HasUsedDataChannels() const;

 protected:
  rtc::Thread* network_thread() const;
  rtc::Thread* signaling_thread() const;

 private:
  void OnSctpDataChannelClosed(SctpDataChannel* channel);

  // Creates a new SctpDataChannel object on the network thread.
  RTCErrorOr<rtc::scoped_refptr<SctpDataChannel>> CreateDataChannel(
      const std::string& label,
      InternalDataChannelInit& config) RTC_RUN_ON(network_thread());

  // Parses and handles open messages.  Returns true if the message is an open
  // message and should be considered to be handled, false otherwise.
  bool HandleOpenMessage_n(int channel_id,
                           DataMessageType type,
                           const rtc::CopyOnWriteBuffer& buffer)
      RTC_RUN_ON(network_thread());
  // Called when a valid data channel OPEN message is received.
  void OnDataChannelOpenMessage(rtc::scoped_refptr<SctpDataChannel> channel,
                                bool ready_to_send)
      RTC_RUN_ON(signaling_thread());

  // Accepts a `StreamId` which may be pre-negotiated or unassigned. For
  // pre-negotiated sids, attempts to reserve the sid in the allocation pool,
  // for unassigned sids attempts to generate a new sid if possible. Returns
  // RTCError::OK() if the sid is reserved (and may have been generated) or
  // if not enough information exists to generate a sid, in which case the sid
  // will still be unassigned upon return, but will be assigned later.
  // If the pool has been exhausted or a sid has already been reserved, an
  // error will be returned.
  RTCError ReserveOrAllocateSid(absl::optional<StreamId>& sid,
                                absl::optional<rtc::SSLRole> fallback_ssl_role)
      RTC_RUN_ON(network_thread());

  // Called when all data channels need to be notified of a transport channel
  // (calls OnTransportChannelCreated on the signaling thread).
  void NotifyDataChannelsOfTransportCreated();

  void set_data_channel_transport(DataChannelTransportInterface* transport);

  // Plugin transport used for data channels.  Pointer may be accessed and
  // checked from any thread, but the object may only be touched on the
  // network thread.
  DataChannelTransportInterface* data_channel_transport_
      RTC_GUARDED_BY(network_thread()) = nullptr;
  SctpSidAllocator sid_allocator_ RTC_GUARDED_BY(network_thread());
  std::vector<rtc::scoped_refptr<SctpDataChannel>> sctp_data_channels_n_
      RTC_GUARDED_BY(network_thread());
  enum class DataChannelUsage : uint8_t {
    kNeverUsed = 0,
    kHaveBeenUsed,
    kInUse
  };
  DataChannelUsage channel_usage_ RTC_GUARDED_BY(signaling_thread()) =
      DataChannelUsage::kNeverUsed;

  // Owning PeerConnection.
  PeerConnectionInternal* const pc_;
  // The weak pointers must be dereferenced and invalidated on the network
  // thread only.
  rtc::WeakPtrFactory<DataChannelController> weak_factory_
      RTC_GUARDED_BY(network_thread()){this};
  ScopedTaskSafety signaling_safety_;
};

}  // namespace webrtc

#endif  // PC_DATA_CHANNEL_CONTROLLER_H_
