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

#include <errno.h>

#include <cstdint>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "absl/types/optional.h"
#include "api/transport/sctp_transport_factory_interface.h"
#include "rtc_base/buffer.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/task_utils/pending_task_safety_flag.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"
// For SendDataParams/ReceiveDataParams.
#include "media/base/media_channel.h"
#include "media/sctp/sctp_transport_internal.h"

// Defined by "usrsctplib/usrsctp.h"
struct sockaddr_conn;
struct sctp_assoc_change;
struct sctp_rcvinfo;
struct sctp_stream_reset_event;
struct sctp_sendv_spa;

// Defined by <sys/socket.h>
struct socket;
namespace cricket {

// Holds data to be passed on to a transport.
struct SctpInboundPacket;

// From transport calls, data flows like this:
// [network thread (although it can in princple be another thread)]
//  1.  SctpTransport::SendData(data)
//  2.  usrsctp_sendv(data)
// [network thread returns; sctp thread then calls the following]
//  3.  OnSctpOutboundPacket(wrapped_data)
// [sctp thread returns having async invoked on the network thread]
//  4.  SctpTransport::OnPacketFromSctpToNetwork(wrapped_data)
//  5.  DtlsTransport::SendPacket(wrapped_data)
//  6.  ... across network ... a packet is sent back ...
//  7.  SctpTransport::OnPacketReceived(wrapped_data)
//  8.  usrsctp_conninput(wrapped_data)
// [network thread returns; sctp thread then calls the following]
//  9.  OnSctpInboundData(data)
//  10. SctpTransport::OnDataFromSctpToTransport(data)
// [sctp thread returns having async invoked on the network thread]
//  11. SctpTransport::OnDataFromSctpToTransport(data)
//  12. SctpTransport::SignalDataReceived(data)
// [from the same thread, methods registered/connected to
//  SctpTransport are called with the recieved data]
class SctpTransport : public SctpTransportInternal,
                      public sigslot::has_slots<> {
 public:
  // |network_thread| is where packets will be processed and callbacks from
  // this transport will be posted, and is the only thread on which public
  // methods can be called.
  // |transport| is not required (can be null).
  SctpTransport(rtc::Thread* network_thread,
                rtc::PacketTransportInternal* transport);
  ~SctpTransport() override;

  // SctpTransportInternal overrides (see sctptransportinternal.h for comments).
  void SetDtlsTransport(rtc::PacketTransportInternal* transport) override;
  bool Start(int local_port, int remote_port, int max_message_size) override;
  bool OpenStream(int sid) override;
  bool ResetStream(int sid) override;
  bool SendData(const SendDataParams& params,
                const rtc::CopyOnWriteBuffer& payload,
                SendDataResult* result = nullptr) override;
  bool ReadyToSendData() override;
  int max_message_size() const override { return max_message_size_; }
  absl::optional<int> max_outbound_streams() const override {
    return max_outbound_streams_;
  }
  absl::optional<int> max_inbound_streams() const override {
    return max_inbound_streams_;
  }
  void set_debug_name_for_testing(const char* debug_name) override {
    debug_name_ = debug_name;
  }
  void InjectDataOrNotificationFromSctpForTesting(const void* data,
                                                  size_t length,
                                                  struct sctp_rcvinfo rcv,
                                                  int flags);

  // Exposed to allow Post call from c-callbacks.
  // TODO(deadbeef): Remove this or at least make it return a const pointer.
  rtc::Thread* network_thread() const { return network_thread_; }

 private:
  // A message to be sent by the sctp library. This class is used to track the
  // progress of writing a single message to the sctp library in the presence of
  // partial writes. In this case, the Advance() function is provided in order
  // to advance over what has already been accepted by the sctp library and
  // avoid copying the remaining partial message buffer.
  class OutgoingMessage {
   public:
    OutgoingMessage(const rtc::CopyOnWriteBuffer& buffer,
                    const SendDataParams& send_params)
        : buffer_(buffer), send_params_(send_params) {}

    // Advances the buffer by the incremented amount. Must not advance further
    // than the current data size.
    void Advance(size_t increment) {
      RTC_DCHECK_LE(increment + offset_, buffer_.size());
      offset_ += increment;
    }

    size_t size() const { return buffer_.size() - offset_; }

    const void* data() const { return buffer_.data() + offset_; }

    SendDataParams send_params() const { return send_params_; }

   private:
    const rtc::CopyOnWriteBuffer buffer_;
    const SendDataParams send_params_;
    size_t offset_ = 0;
  };

  void ConnectTransportSignals();
  void DisconnectTransportSignals();

  // Creates the socket and connects.
  bool Connect();

  // Returns false when opening the socket failed.
  bool OpenSctpSocket();
  // Helpet method to set socket options.
  bool ConfigureSctpSocket();
  // Sets |sock_ |to nullptr.
  void CloseSctpSocket();

  // Sends a SCTP_RESET_STREAM for all streams in closing_ssids_.
  bool SendQueuedStreamResets();

  // Sets the "ready to send" flag and fires signal if needed.
  void SetReadyToSendData();

  // Sends the outgoing buffered message that was only partially accepted by the
  // sctp lib because it did not have enough space. Returns true if the entire
  // buffered message was accepted by the sctp lib.
  bool SendBufferedMessage();

  // Tries to send the |payload| on the usrsctp lib. The message will be
  // advanced by the amount that was sent.
  SendDataResult SendMessageInternal(OutgoingMessage* message);

  // Callbacks from DTLS transport.
  void OnWritableState(rtc::PacketTransportInternal* transport);
  virtual void OnPacketRead(rtc::PacketTransportInternal* transport,
                            const char* data,
                            size_t len,
                            const int64_t& packet_time_us,
                            int flags);
  void OnClosed(rtc::PacketTransportInternal* transport);

  // Methods related to usrsctp callbacks.
  void OnSendThresholdCallback();
  sockaddr_conn GetSctpSockAddr(int port);

  // Called using |invoker_| to send packet on the network.
  void OnPacketFromSctpToNetwork(const rtc::CopyOnWriteBuffer& buffer);

  // Called on the network thread.
  // Flags are standard socket API flags (RFC 6458).
  void OnDataOrNotificationFromSctp(const void* data,
                                    size_t length,
                                    struct sctp_rcvinfo rcv,
                                    int flags);
  // Called using |invoker_| to decide what to do with the data.
  void OnDataFromSctpToTransport(const ReceiveDataParams& params,
                                 const rtc::CopyOnWriteBuffer& buffer);
  // Called using |invoker_| to decide what to do with the notification.
  void OnNotificationFromSctp(const rtc::CopyOnWriteBuffer& buffer);
  void OnNotificationAssocChange(const sctp_assoc_change& change);

  void OnStreamResetEvent(const struct sctp_stream_reset_event* evt);

  // Responsible for marshalling incoming data to the transports listeners, and
  // outgoing data to the network interface.
  rtc::Thread* network_thread_;
  // Helps pass inbound/outbound packets asynchronously to the network thread.
  webrtc::ScopedTaskSafety task_safety_;
  // Underlying DTLS transport.
  rtc::PacketTransportInternal* transport_ = nullptr;

  // Track the data received from usrsctp between callbacks until the EOR bit
  // arrives.
  rtc::CopyOnWriteBuffer partial_incoming_message_;
  ReceiveDataParams partial_params_;
  int partial_flags_;
  // A message that was attempted to be sent, but was only partially accepted by
  // usrsctp lib with usrsctp_sendv() because it cannot buffer the full message.
  // This occurs because we explicitly set the EOR bit when sending, so
  // usrsctp_sendv() is not atomic.
  absl::optional<OutgoingMessage> partial_outgoing_message_;

  bool was_ever_writable_ = false;
  int local_port_ = kSctpDefaultPort;
  int remote_port_ = kSctpDefaultPort;
  int max_message_size_ = kSctpSendBufferSize;
  struct socket* sock_ = nullptr;  // The socket created by usrsctp_socket(...).

  // Has Start been called? Don't create SCTP socket until it has.
  bool started_ = false;
  // Are we ready to queue data (SCTP socket created, and not blocked due to
  // congestion control)? Different than |transport_|'s "ready to send".
  bool ready_to_send_data_ = false;

  // Used to keep track of the status of each stream (or rather, each pair of
  // incoming/outgoing streams with matching IDs). It's specifically used to
  // keep track of the status of resets, but more information could be put here
  // later.
  //
  // See datachannel.h for a summary of the closing procedure.
  struct StreamStatus {
    // Closure initiated by application via ResetStream? Note that
    // this may be true while outgoing_reset_initiated is false if the outgoing
    // reset needed to be queued.
    bool closure_initiated = false;
    // Whether we've initiated the outgoing stream reset via
    // SCTP_RESET_STREAMS.
    bool outgoing_reset_initiated = false;
    // Whether usrsctp has indicated that the incoming/outgoing streams have
    // been reset. It's expected that the peer will reset its outgoing stream
    // (our incoming stream) after receiving the reset for our outgoing stream,
    // though older versions of chromium won't do this. See crbug.com/559394
    // for context.
    bool outgoing_reset_complete = false;
    bool incoming_reset_complete = false;

    // Some helper methods to improve code readability.
    bool is_open() const {
      return !closure_initiated && !incoming_reset_complete &&
             !outgoing_reset_complete;
    }
    // We need to send an outgoing reset if the application has closed the data
    // channel, or if we received a reset of the incoming stream from the
    // remote endpoint, indicating the data channel was closed remotely.
    bool need_outgoing_reset() const {
      return (incoming_reset_complete || closure_initiated) &&
             !outgoing_reset_initiated;
    }
    bool reset_complete() const {
      return outgoing_reset_complete && incoming_reset_complete;
    }
  };

  // Entries should only be removed from this map if |reset_complete| is
  // true.
  std::map<uint32_t, StreamStatus> stream_status_by_sid_;

  // A static human-readable name for debugging messages.
  const char* debug_name_ = "SctpTransport";
  // Hides usrsctp interactions from this header file.
  class UsrSctpWrapper;
  // Number of channels negotiated. Not set before negotiation completes.
  absl::optional<int> max_outbound_streams_;
  absl::optional<int> max_inbound_streams_;

  // Used for associating this transport with the underlying sctp socket in
  // various callbacks.
  uintptr_t id_ = 0;

  friend class SctpTransportMap;

  RTC_DISALLOW_COPY_AND_ASSIGN(SctpTransport);
};

class SctpTransportFactory : public webrtc::SctpTransportFactoryInterface {
 public:
  explicit SctpTransportFactory(rtc::Thread* network_thread)
      : network_thread_(network_thread) {}

  std::unique_ptr<SctpTransportInternal> CreateSctpTransport(
      rtc::PacketTransportInternal* transport) override {
    return std::unique_ptr<SctpTransportInternal>(
        new SctpTransport(network_thread_, transport));
  }

 private:
  rtc::Thread* network_thread_;
};

class SctpTransportMap;

}  // namespace cricket

#endif  // MEDIA_SCTP_SCTP_TRANSPORT_H_
