/*
 *  Copyright 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.
 */

// This file contains interfaces for DataChannels
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcdatachannel

#ifndef API_DATACHANNELINTERFACE_H_
#define API_DATACHANNELINTERFACE_H_

#include <string>

#include "rtc_base/checks.h"
#include "rtc_base/copyonwritebuffer.h"
#include "rtc_base/refcount.h"

namespace webrtc {

// C++ version of: https://www.w3.org/TR/webrtc/#idl-def-rtcdatachannelinit
// TODO(deadbeef): Use absl::optional for the "-1 if unset" things.
struct DataChannelInit {
  // Deprecated. Reliability is assumed, and channel will be unreliable if
  // maxRetransmitTime or MaxRetransmits is set.
  bool reliable = false;

  // True if ordered delivery is required.
  bool ordered = true;

  // The max period of time in milliseconds in which retransmissions will be
  // sent. After this time, no more retransmissions will be sent. -1 if unset.
  //
  // Cannot be set along with |maxRetransmits|.
  int maxRetransmitTime = -1;

  // The max number of retransmissions. -1 if unset.
  //
  // Cannot be set along with |maxRetransmitTime|.
  int maxRetransmits = -1;

  // This is set by the application and opaque to the WebRTC implementation.
  std::string protocol;

  // True if the channel has been externally negotiated and we do not send an
  // in-band signalling in the form of an "open" message. If this is true, |id|
  // below must be set; otherwise it should be unset and will be negotiated
  // in-band.
  bool negotiated = false;

  // The stream id, or SID, for SCTP data channels. -1 if unset (see above).
  int id = -1;
};

// At the JavaScript level, data can be passed in as a string or a blob, so
// this structure's |binary| flag tells whether the data should be interpreted
// as binary or text.
struct DataBuffer {
  DataBuffer(const rtc::CopyOnWriteBuffer& data, bool binary)
      : data(data), binary(binary) {}
  // For convenience for unit tests.
  explicit DataBuffer(const std::string& text)
      : data(text.data(), text.length()), binary(false) {}
  size_t size() const { return data.size(); }

  rtc::CopyOnWriteBuffer data;
  // Indicates if the received data contains UTF-8 or binary data.
  // Note that the upper layers are left to verify the UTF-8 encoding.
  // TODO(jiayl): prefer to use an enum instead of a bool.
  bool binary;
};

// Used to implement RTCDataChannel events.
//
// The code responding to these callbacks should unwind the stack before
// using any other webrtc APIs; re-entrancy is not supported.
class DataChannelObserver {
 public:
  // The data channel state have changed.
  virtual void OnStateChange() = 0;
  //  A data buffer was successfully received.
  virtual void OnMessage(const DataBuffer& buffer) = 0;
  // The data channel's buffered_amount has changed.
  virtual void OnBufferedAmountChange(uint64_t previous_amount) {}

 protected:
  virtual ~DataChannelObserver() {}
};

class DataChannelInterface : public rtc::RefCountInterface {
 public:
  // C++ version of: https://www.w3.org/TR/webrtc/#idl-def-rtcdatachannelstate
  // Unlikely to change, but keep in sync with DataChannel.java:State and
  // RTCDataChannel.h:RTCDataChannelState.
  enum DataState {
    kConnecting,
    kOpen,  // The DataChannel is ready to send data.
    kClosing,
    kClosed
  };

  static const char* DataStateString(DataState state) {
    switch (state) {
      case kConnecting:
        return "connecting";
      case kOpen:
        return "open";
      case kClosing:
        return "closing";
      case kClosed:
        return "closed";
    }
    RTC_CHECK(false) << "Unknown DataChannel state: " << state;
    return "";
  }

  // Used to receive events from the data channel. Only one observer can be
  // registered at a time. UnregisterObserver should be called before the
  // observer object is destroyed.
  virtual void RegisterObserver(DataChannelObserver* observer) = 0;
  virtual void UnregisterObserver() = 0;

  // The label attribute represents a label that can be used to distinguish this
  // DataChannel object from other DataChannel objects.
  virtual std::string label() const = 0;

  // The accessors below simply return the properties from the DataChannelInit
  // the data channel was constructed with.
  virtual bool reliable() const = 0;
  // TODO(deadbeef): Remove these dummy implementations when all classes have
  // implemented these APIs. They should all just return the values the
  // DataChannel was created with.
  virtual bool ordered() const { return false; }
  virtual uint16_t maxRetransmitTime() const { return 0; }
  virtual uint16_t maxRetransmits() const { return 0; }
  virtual std::string protocol() const { return std::string(); }
  virtual bool negotiated() const { return false; }

  // Returns the ID from the DataChannelInit, if it was negotiated out-of-band.
  // If negotiated in-band, this ID will be populated once the DTLS role is
  // determined, and until then this will return -1.
  virtual int id() const = 0;
  virtual DataState state() const = 0;
  virtual uint32_t messages_sent() const = 0;
  virtual uint64_t bytes_sent() const = 0;
  virtual uint32_t messages_received() const = 0;
  virtual uint64_t bytes_received() const = 0;

  // Returns the number of bytes of application data (UTF-8 text and binary
  // data) that have been queued using Send but have not yet been processed at
  // the SCTP level. See comment above Send below.
  virtual uint64_t buffered_amount() const = 0;

  // Begins the graceful data channel closing procedure. See:
  // https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-13#section-6.7
  virtual void Close() = 0;

  // Sends |data| to the remote peer. If the data can't be sent at the SCTP
  // level (due to congestion control), it's buffered at the data channel level,
  // up to a maximum of 16MB. If Send is called while this buffer is full, the
  // data channel will be closed abruptly.
  //
  // So, it's important to use buffered_amount() and OnBufferedAmountChange to
  // ensure the data channel is used efficiently but without filling this
  // buffer.
  virtual bool Send(const DataBuffer& buffer) = 0;

 protected:
  virtual ~DataChannelInterface() {}
};

}  // namespace webrtc

#endif  // API_DATACHANNELINTERFACE_H_
