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

#include "webrtc/api/quicdatachannel.h"

#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "webrtc/base/bind.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/p2p/base/faketransportcontroller.h"
#include "webrtc/p2p/quic/quictransportchannel.h"
#include "webrtc/p2p/quic/reliablequicstream.h"

using cricket::FakeTransportChannel;
using cricket::QuicTransportChannel;
using cricket::ReliableQuicStream;

using webrtc::DataBuffer;
using webrtc::DataChannelObserver;
using webrtc::DataChannelInit;
using webrtc::QuicDataChannel;

namespace {

// Timeout for asynchronous operations.
static const int kTimeoutMs = 1000;  // milliseconds

// Small messages that can be sent within a single QUIC packet.
static const std::string kSmallMessage1 = "Hello, world!";
static const std::string kSmallMessage2 = "WebRTC";
static const std::string kSmallMessage3 = "1";
static const std::string kSmallMessage4 = "abcdefghijklmnopqrstuvwxyz";
static const DataBuffer kSmallBuffer1(kSmallMessage1);
static const DataBuffer kSmallBuffer2(kSmallMessage2);
static const DataBuffer kSmallBuffer3(kSmallMessage3);
static const DataBuffer kSmallBuffer4(kSmallMessage4);

// Large messages (> 1350 bytes) that exceed the max size of a QUIC packet.
// These are < 16 KB so they don't exceed the QUIC stream flow control limit.
static const std::string kLargeMessage1 = std::string("a", 2000);
static const std::string kLargeMessage2 = std::string("a", 4000);
static const std::string kLargeMessage3 = std::string("a", 8000);
static const std::string kLargeMessage4 = std::string("a", 12000);
static const DataBuffer kLargeBuffer1(kLargeMessage1);
static const DataBuffer kLargeBuffer2(kLargeMessage2);
static const DataBuffer kLargeBuffer3(kLargeMessage3);
static const DataBuffer kLargeBuffer4(kLargeMessage4);

// Oversized message (> 16 KB) that violates the QUIC stream flow control limit.
static const std::string kOversizedMessage = std::string("a", 20000);
static const DataBuffer kOversizedBuffer(kOversizedMessage);

// Creates a fingerprint from a certificate.
static rtc::SSLFingerprint* CreateFingerprint(rtc::RTCCertificate* cert) {
  std::string digest_algorithm;
  cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_algorithm);
  std::unique_ptr<rtc::SSLFingerprint> fingerprint(
      rtc::SSLFingerprint::Create(digest_algorithm, cert->identity()));
  return fingerprint.release();
}

// FakeObserver receives messages from the QuicDataChannel.
class FakeObserver : public DataChannelObserver {
 public:
  FakeObserver()
      : on_state_change_count_(0), on_buffered_amount_change_count_(0) {}

  // DataChannelObserver overrides.
  void OnStateChange() override { ++on_state_change_count_; }
  void OnBufferedAmountChange(uint64_t previous_amount) override {
    ++on_buffered_amount_change_count_;
  }
  void OnMessage(const webrtc::DataBuffer& buffer) override {
    messages_.push_back(std::string(buffer.data.data<char>(), buffer.size()));
  }

  const std::vector<std::string>& messages() const { return messages_; }

  size_t messages_received() const { return messages_.size(); }

  size_t on_state_change_count() const { return on_state_change_count_; }

  size_t on_buffered_amount_change_count() const {
    return on_buffered_amount_change_count_;
  }

 private:
  std::vector<std::string> messages_;
  size_t on_state_change_count_;
  size_t on_buffered_amount_change_count_;
};

// FakeQuicDataTransport simulates QuicDataTransport by dispatching QUIC
// stream messages to data channels and encoding/decoding messages.
class FakeQuicDataTransport : public sigslot::has_slots<> {
 public:
  FakeQuicDataTransport() {}

  void ConnectToTransportChannel(QuicTransportChannel* quic_transport_channel) {
    quic_transport_channel->SignalIncomingStream.connect(
        this, &FakeQuicDataTransport::OnIncomingStream);
  }

  rtc::scoped_refptr<QuicDataChannel> CreateDataChannel(
      int id,
      const std::string& label,
      const std::string& protocol) {
    DataChannelInit config;
    config.id = id;
    config.protocol = protocol;
    rtc::scoped_refptr<QuicDataChannel> data_channel(
        new QuicDataChannel(rtc::Thread::Current(), rtc::Thread::Current(),
                            rtc::Thread::Current(), label, config));
    data_channel_by_id_[id] = data_channel;
    return data_channel;
  }

 private:
  void OnIncomingStream(cricket::ReliableQuicStream* stream) {
    incoming_stream_ = stream;
    incoming_stream_->SignalDataReceived.connect(
        this, &FakeQuicDataTransport::OnDataReceived);
  }

  void OnDataReceived(net::QuicStreamId id, const char* data, size_t len) {
    ASSERT_EQ(incoming_stream_->id(), id);
    incoming_stream_->SignalDataReceived.disconnect(this);
    // Retrieve the data channel ID and message ID.
    int data_channel_id;
    uint64_t message_id;
    size_t bytes_read;
    ASSERT_TRUE(webrtc::ParseQuicDataMessageHeader(data, len, &data_channel_id,
                                                   &message_id, &bytes_read));
    data += bytes_read;
    len -= bytes_read;
    // Dispatch the message to the matching QuicDataChannel.
    const auto& kv = data_channel_by_id_.find(data_channel_id);
    ASSERT_NE(kv, data_channel_by_id_.end());
    QuicDataChannel* data_channel = kv->second;
    QuicDataChannel::Message message;
    message.id = message_id;
    message.buffer = rtc::CopyOnWriteBuffer(data, len);
    message.stream = incoming_stream_;
    data_channel->OnIncomingMessage(std::move(message));
    incoming_stream_ = nullptr;
  }

  // Map of data channel ID => QuicDataChannel.
  std::map<int, rtc::scoped_refptr<QuicDataChannel>> data_channel_by_id_;
  // Last incoming QUIC stream which has arrived.
  cricket::ReliableQuicStream* incoming_stream_ = nullptr;
};

// A peer who creates a QuicDataChannel to transfer data, and simulates network
// connectivity with a fake ICE channel wrapped by the QUIC transport channel.
class QuicDataChannelPeer {
 public:
  QuicDataChannelPeer()
      : ice_transport_channel_(new FakeTransportChannel("data", 0)),
        quic_transport_channel_(ice_transport_channel_) {
    ice_transport_channel_->SetAsync(true);
    fake_quic_data_transport_.ConnectToTransportChannel(
        &quic_transport_channel_);
  }

  void GenerateCertificateAndFingerprint() {
    rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
        rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
            rtc::SSLIdentity::Generate("cert_name", rtc::KT_DEFAULT)));
    quic_transport_channel_.SetLocalCertificate(local_cert);
    local_fingerprint_.reset(CreateFingerprint(local_cert.get()));
  }

  rtc::scoped_refptr<QuicDataChannel> CreateDataChannelWithTransportChannel(
      int id,
      const std::string& label,
      const std::string& protocol) {
    rtc::scoped_refptr<QuicDataChannel> data_channel =
        fake_quic_data_transport_.CreateDataChannel(id, label, protocol);
    data_channel->SetTransportChannel(&quic_transport_channel_);
    return data_channel;
  }

  rtc::scoped_refptr<QuicDataChannel> CreateDataChannelWithoutTransportChannel(
      int id,
      const std::string& label,
      const std::string& protocol) {
    return fake_quic_data_transport_.CreateDataChannel(id, label, protocol);
  }

  // Connects |ice_transport_channel_| to that of the other peer.
  void Connect(QuicDataChannelPeer* other_peer) {
    ice_transport_channel_->SetDestination(other_peer->ice_transport_channel_);
  }

  std::unique_ptr<rtc::SSLFingerprint>& local_fingerprint() {
    return local_fingerprint_;
  }

  QuicTransportChannel* quic_transport_channel() {
    return &quic_transport_channel_;
  }

  FakeTransportChannel* ice_transport_channel() {
    return ice_transport_channel_;
  }

 private:
  FakeTransportChannel* ice_transport_channel_;
  QuicTransportChannel quic_transport_channel_;

  std::unique_ptr<rtc::SSLFingerprint> local_fingerprint_;

  FakeQuicDataTransport fake_quic_data_transport_;
};

class QuicDataChannelTest : public testing::Test {
 public:
  QuicDataChannelTest() {}

  // Connect the QuicTransportChannels and complete the crypto handshake.
  void ConnectTransportChannels() {
    SetCryptoParameters();
    peer1_.Connect(&peer2_);
    ASSERT_TRUE_WAIT(peer1_.quic_transport_channel()->writable() &&
                         peer2_.quic_transport_channel()->writable(),
                     kTimeoutMs);
  }

  // Sets crypto parameters required for the QUIC handshake.
  void SetCryptoParameters() {
    peer1_.GenerateCertificateAndFingerprint();
    peer2_.GenerateCertificateAndFingerprint();

    peer1_.quic_transport_channel()->SetSslRole(rtc::SSL_CLIENT);
    peer2_.quic_transport_channel()->SetSslRole(rtc::SSL_SERVER);

    std::unique_ptr<rtc::SSLFingerprint>& peer1_fingerprint =
        peer1_.local_fingerprint();
    std::unique_ptr<rtc::SSLFingerprint>& peer2_fingerprint =
        peer2_.local_fingerprint();

    peer1_.quic_transport_channel()->SetRemoteFingerprint(
        peer2_fingerprint->algorithm,
        reinterpret_cast<const uint8_t*>(peer2_fingerprint->digest.data()),
        peer2_fingerprint->digest.size());
    peer2_.quic_transport_channel()->SetRemoteFingerprint(
        peer1_fingerprint->algorithm,
        reinterpret_cast<const uint8_t*>(peer1_fingerprint->digest.data()),
        peer1_fingerprint->digest.size());
  }

 protected:
  QuicDataChannelPeer peer1_;
  QuicDataChannelPeer peer2_;
};

// Tests that a QuicDataChannel transitions from connecting to open when
// the QuicTransportChannel becomes writable for the first time.
TEST_F(QuicDataChannelTest, DataChannelOpensWhenTransportChannelConnects) {
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithTransportChannel(4, "label", "protocol");
  EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, data_channel->state());
  ConnectTransportChannels();
  EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, data_channel->state(),
                 kTimeoutMs);
}

// Tests that a QuicDataChannel transitions from connecting to open when
// SetTransportChannel is called with a QuicTransportChannel that is already
// writable.
TEST_F(QuicDataChannelTest, DataChannelOpensWhenTransportChannelWritable) {
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithoutTransportChannel(4, "label", "protocol");
  ConnectTransportChannels();
  EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, data_channel->state());
  data_channel->SetTransportChannel(peer1_.quic_transport_channel());
  EXPECT_EQ(webrtc::DataChannelInterface::kOpen, data_channel->state());
}

// Tests that the QuicDataChannel transfers messages small enough to fit into a
// single QUIC stream frame.
TEST_F(QuicDataChannelTest, TransferSmallMessage) {
  ConnectTransportChannels();
  int data_channel_id = 2;
  std::string label = "label";
  std::string protocol = "protocol";
  rtc::scoped_refptr<QuicDataChannel> peer1_data_channel =
      peer1_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  ASSERT_TRUE(peer1_data_channel->state() ==
              webrtc::DataChannelInterface::kOpen);
  rtc::scoped_refptr<QuicDataChannel> peer2_data_channel =
      peer2_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  ASSERT_TRUE(peer2_data_channel->state() ==
              webrtc::DataChannelInterface::kOpen);

  FakeObserver peer1_observer;
  peer1_data_channel->RegisterObserver(&peer1_observer);
  FakeObserver peer2_observer;
  peer2_data_channel->RegisterObserver(&peer2_observer);

  // peer1 -> peer2
  EXPECT_TRUE(peer1_data_channel->Send(kSmallBuffer1));
  ASSERT_EQ_WAIT(1, peer2_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ(kSmallMessage1, peer2_observer.messages()[0]);
  // peer2 -> peer1
  EXPECT_TRUE(peer2_data_channel->Send(kSmallBuffer2));
  ASSERT_EQ_WAIT(1, peer1_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ(kSmallMessage2, peer1_observer.messages()[0]);
  // peer2 -> peer1
  EXPECT_TRUE(peer2_data_channel->Send(kSmallBuffer3));
  ASSERT_EQ_WAIT(2, peer1_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ(kSmallMessage3, peer1_observer.messages()[1]);
  // peer1 -> peer2
  EXPECT_TRUE(peer1_data_channel->Send(kSmallBuffer4));
  ASSERT_EQ_WAIT(2, peer2_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ(kSmallMessage4, peer2_observer.messages()[1]);
}

// Tests that QuicDataChannel transfers messages large enough to fit into
// multiple QUIC stream frames, which don't violate the QUIC flow control limit.
// These require buffering by the QuicDataChannel.
TEST_F(QuicDataChannelTest, TransferLargeMessage) {
  ConnectTransportChannels();
  int data_channel_id = 347;
  std::string label = "label";
  std::string protocol = "protocol";
  rtc::scoped_refptr<QuicDataChannel> peer1_data_channel =
      peer1_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  ASSERT_TRUE(peer1_data_channel->state() ==
              webrtc::DataChannelInterface::kOpen);
  rtc::scoped_refptr<QuicDataChannel> peer2_data_channel =
      peer2_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  ASSERT_TRUE(peer2_data_channel->state() ==
              webrtc::DataChannelInterface::kOpen);

  FakeObserver peer1_observer;
  peer1_data_channel->RegisterObserver(&peer1_observer);
  FakeObserver peer2_observer;
  peer2_data_channel->RegisterObserver(&peer2_observer);

  // peer1 -> peer2
  EXPECT_TRUE(peer1_data_channel->Send(kLargeBuffer1));
  ASSERT_TRUE_WAIT(peer2_observer.messages_received() == 1, kTimeoutMs);
  EXPECT_EQ(kLargeMessage1, peer2_observer.messages()[0]);
  // peer2 -> peer1
  EXPECT_TRUE(peer2_data_channel->Send(kLargeBuffer2));
  ASSERT_EQ_WAIT(1, peer1_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ(kLargeMessage2, peer1_observer.messages()[0]);
  // peer2 -> peer1
  EXPECT_TRUE(peer2_data_channel->Send(kLargeBuffer3));
  ASSERT_EQ_WAIT(2, peer1_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ(kLargeMessage3, peer1_observer.messages()[1]);
  // peer1 -> peer2
  EXPECT_TRUE(peer1_data_channel->Send(kLargeBuffer4));
  ASSERT_EQ_WAIT(2, peer2_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ(kLargeMessage4, peer2_observer.messages()[1]);
}

// Tests that when a message size exceeds the flow control limit (> 16KB), the
// QuicDataChannel can queue the data and send it after receiving window update
// frames from the remote peer.
TEST_F(QuicDataChannelTest, TransferOversizedMessage) {
  ConnectTransportChannels();
  int data_channel_id = 189;
  std::string label = "label";
  std::string protocol = "protocol";
  rtc::scoped_refptr<QuicDataChannel> peer1_data_channel =
      peer1_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  rtc::scoped_refptr<QuicDataChannel> peer2_data_channel =
      peer2_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  ASSERT_TRUE(peer2_data_channel->state() ==
              webrtc::DataChannelInterface::kOpen);

  FakeObserver peer1_observer;
  peer1_data_channel->RegisterObserver(&peer1_observer);
  FakeObserver peer2_observer;
  peer2_data_channel->RegisterObserver(&peer2_observer);

  EXPECT_TRUE(peer1_data_channel->Send(kOversizedBuffer));
  EXPECT_EQ(1, peer1_data_channel->GetNumWriteBlockedStreams());
  EXPECT_EQ_WAIT(1, peer2_data_channel->GetNumIncomingStreams(), kTimeoutMs);
  ASSERT_EQ_WAIT(1, peer2_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ(kOversizedMessage, peer2_observer.messages()[0]);
  EXPECT_EQ(0, peer1_data_channel->GetNumWriteBlockedStreams());
  EXPECT_EQ(0, peer2_data_channel->GetNumIncomingStreams());
}

// Tests that empty messages can be sent.
TEST_F(QuicDataChannelTest, TransferEmptyMessage) {
  ConnectTransportChannels();
  int data_channel_id = 69;
  std::string label = "label";
  std::string protocol = "protocol";
  rtc::scoped_refptr<QuicDataChannel> peer1_data_channel =
      peer1_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  rtc::scoped_refptr<QuicDataChannel> peer2_data_channel =
      peer2_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  ASSERT_TRUE(peer2_data_channel->state() ==
              webrtc::DataChannelInterface::kOpen);

  FakeObserver peer1_observer;
  peer1_data_channel->RegisterObserver(&peer1_observer);
  FakeObserver peer2_observer;
  peer2_data_channel->RegisterObserver(&peer2_observer);

  EXPECT_TRUE(peer1_data_channel->Send(DataBuffer("")));
  ASSERT_EQ_WAIT(1, peer2_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ("", peer2_observer.messages()[0]);
}

// Tests that when the QuicDataChannel is open and sends a message while the
// QuicTransportChannel is unwritable, it gets buffered then received once the
// QuicTransportChannel becomes writable again.
TEST_F(QuicDataChannelTest, MessagesReceivedWhenTransportChannelReconnects) {
  ConnectTransportChannels();
  int data_channel_id = 401;
  std::string label = "label";
  std::string protocol = "protocol";
  rtc::scoped_refptr<QuicDataChannel> peer1_data_channel =
      peer1_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  ASSERT_TRUE(peer1_data_channel->state() ==
              webrtc::DataChannelInterface::kOpen);
  rtc::scoped_refptr<QuicDataChannel> peer2_data_channel =
      peer2_.CreateDataChannelWithTransportChannel(data_channel_id, label,
                                                   protocol);
  ASSERT_TRUE(peer2_data_channel->state() ==
              webrtc::DataChannelInterface::kOpen);

  FakeObserver peer1_observer;
  peer1_data_channel->RegisterObserver(&peer1_observer);
  FakeObserver peer2_observer;
  peer2_data_channel->RegisterObserver(&peer2_observer);
  // writable => unwritable
  peer1_.ice_transport_channel()->SetWritable(false);
  ASSERT_FALSE(peer1_.quic_transport_channel()->writable());
  // Verify that sent data is buffered.
  EXPECT_TRUE(peer1_data_channel->Send(kSmallBuffer1));
  EXPECT_EQ(1, peer1_data_channel->GetNumWriteBlockedStreams());
  EXPECT_TRUE(peer1_data_channel->Send(kSmallBuffer2));
  EXPECT_EQ(2, peer1_data_channel->GetNumWriteBlockedStreams());
  EXPECT_TRUE(peer1_data_channel->Send(kSmallBuffer3));
  EXPECT_EQ(3, peer1_data_channel->GetNumWriteBlockedStreams());
  EXPECT_TRUE(peer1_data_channel->Send(kSmallBuffer4));
  EXPECT_EQ(4, peer1_data_channel->GetNumWriteBlockedStreams());
  // unwritable => writable
  peer1_.ice_transport_channel()->SetWritable(true);
  ASSERT_TRUE(peer1_.quic_transport_channel()->writable());
  ASSERT_EQ_WAIT(4, peer2_observer.messages_received(), kTimeoutMs);
  EXPECT_EQ(0, peer1_data_channel->GetNumWriteBlockedStreams());
  EXPECT_EQ(0, peer2_data_channel->GetNumIncomingStreams());
}

// Tests that the QuicDataChannel does not send before it is open.
TEST_F(QuicDataChannelTest, TransferMessageBeforeChannelOpens) {
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithTransportChannel(6, "label", "protocol");
  ASSERT_TRUE(data_channel->state() ==
              webrtc::DataChannelInterface::kConnecting);
  EXPECT_FALSE(data_channel->Send(kSmallBuffer1));
}

// Tests that the QuicDataChannel does not send after it is closed.
TEST_F(QuicDataChannelTest, TransferDataAfterChannelClosed) {
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithTransportChannel(42, "label", "protocol");
  data_channel->Close();
  ASSERT_EQ_WAIT(webrtc::DataChannelInterface::kClosed, data_channel->state(),
                 kTimeoutMs);
  EXPECT_FALSE(data_channel->Send(kSmallBuffer1));
}

// Tests that QuicDataChannel state changes fire OnStateChanged() for the
// observer, with the correct data channel states, when the data channel
// transitions from kConnecting => kOpen => kClosing => kClosed.
TEST_F(QuicDataChannelTest, OnStateChangedFired) {
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithTransportChannel(7, "label", "protocol");
  FakeObserver observer;
  data_channel->RegisterObserver(&observer);
  EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, data_channel->state());
  EXPECT_EQ(0, observer.on_state_change_count());
  ConnectTransportChannels();
  EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, data_channel->state(),
                 kTimeoutMs);
  EXPECT_EQ(1, observer.on_state_change_count());
  data_channel->Close();
  EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed, data_channel->state(),
                 kTimeoutMs);
  // 2 state changes due to kClosing and kClosed.
  EXPECT_EQ(3, observer.on_state_change_count());
}

// Tests that a QuicTransportChannel can be closed without being opened when it
// is connected to a transprot chanenl.
TEST_F(QuicDataChannelTest, NeverOpenedWithTransportChannel) {
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithTransportChannel(7, "label", "protocol");
  EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, data_channel->state());
  data_channel->Close();
  EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed, data_channel->state(),
                 kTimeoutMs);
}

// Tests that a QuicTransportChannel can be closed without being opened or
// connected to a transport channel.
TEST_F(QuicDataChannelTest, NeverOpenedWithoutTransportChannel) {
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithoutTransportChannel(7, "label", "protocol");
  EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, data_channel->state());
  data_channel->Close();
  EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed, data_channel->state(),
                 kTimeoutMs);
}

// Tests that the QuicDataChannel is closed when the QUIC connection closes.
TEST_F(QuicDataChannelTest, ClosedOnTransportError) {
  ConnectTransportChannels();
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithTransportChannel(1, "label", "protocol");
  EXPECT_EQ(webrtc::DataChannelInterface::kOpen, data_channel->state());
  ReliableQuicStream* stream =
      peer1_.quic_transport_channel()->CreateQuicStream();
  ASSERT_NE(nullptr, stream);
  stream->CloseConnectionWithDetails(net::QuicErrorCode::QUIC_NO_ERROR,
                                     "Closing QUIC for testing");
  EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed, data_channel->state(),
                 kTimeoutMs);
}

// Tests that an already closed QuicDataChannel does not fire onStateChange and
// remains closed.
TEST_F(QuicDataChannelTest, DoesNotChangeStateWhenClosed) {
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithTransportChannel(4, "label", "protocol");
  FakeObserver observer;
  data_channel->RegisterObserver(&observer);
  data_channel->Close();
  EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed, data_channel->state(),
                 kTimeoutMs);
  // OnStateChange called for kClosing and kClosed.
  EXPECT_EQ(2, observer.on_state_change_count());
  // Call Close() again to verify that the state cannot be kClosing.
  data_channel->Close();
  EXPECT_EQ(webrtc::DataChannelInterface::kClosed, data_channel->state());
  EXPECT_EQ(2, observer.on_state_change_count());
  ConnectTransportChannels();
  EXPECT_EQ(webrtc::DataChannelInterface::kClosed, data_channel->state());
  EXPECT_EQ(2, observer.on_state_change_count());
  // writable => unwritable
  peer1_.ice_transport_channel()->SetWritable(false);
  ASSERT_FALSE(peer1_.quic_transport_channel()->writable());
  EXPECT_EQ(webrtc::DataChannelInterface::kClosed, data_channel->state());
  EXPECT_EQ(2, observer.on_state_change_count());
  // unwritable => writable
  peer1_.ice_transport_channel()->SetWritable(true);
  ASSERT_TRUE(peer1_.quic_transport_channel()->writable());
  EXPECT_EQ(webrtc::DataChannelInterface::kClosed, data_channel->state());
  EXPECT_EQ(2, observer.on_state_change_count());
}

// Tests that when the QuicDataChannel is open and the QuicTransportChannel
// transitions between writable and unwritable, it does not fire onStateChange
// and remains open.
TEST_F(QuicDataChannelTest, DoesNotChangeStateWhenTransportChannelReconnects) {
  ConnectTransportChannels();
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithTransportChannel(4, "label", "protocol");
  FakeObserver observer;
  data_channel->RegisterObserver(&observer);
  EXPECT_EQ(webrtc::DataChannelInterface::kOpen, data_channel->state());
  EXPECT_EQ(0, observer.on_state_change_count());
  // writable => unwritable
  peer1_.ice_transport_channel()->SetWritable(false);
  ASSERT_FALSE(peer1_.quic_transport_channel()->writable());
  EXPECT_EQ(webrtc::DataChannelInterface::kOpen, data_channel->state());
  EXPECT_EQ(0, observer.on_state_change_count());
  // unwritable => writable
  peer1_.ice_transport_channel()->SetWritable(true);
  ASSERT_TRUE(peer1_.quic_transport_channel()->writable());
  EXPECT_EQ(webrtc::DataChannelInterface::kOpen, data_channel->state());
  EXPECT_EQ(0, observer.on_state_change_count());
}

// Tests that SetTransportChannel returns false when setting a NULL transport
// channel or a transport channel that is not equivalent to the one already set.
TEST_F(QuicDataChannelTest, SetTransportChannelReturnValue) {
  rtc::scoped_refptr<QuicDataChannel> data_channel =
      peer1_.CreateDataChannelWithTransportChannel(4, "label", "protocol");
  EXPECT_FALSE(data_channel->SetTransportChannel(nullptr));
  QuicTransportChannel* transport_channel = peer1_.quic_transport_channel();
  EXPECT_TRUE(data_channel->SetTransportChannel(transport_channel));
  EXPECT_TRUE(data_channel->SetTransportChannel(transport_channel));
  QuicTransportChannel* other_transport_channel =
      peer2_.quic_transport_channel();
  EXPECT_FALSE(data_channel->SetTransportChannel(other_transport_channel));
}

// Tests that the QUIC message header is encoded with the correct number of
// bytes and is properly decoded.
TEST_F(QuicDataChannelTest, EncodeParseQuicDataMessageHeader) {
  int data_channel_id1 = 127;  // 1 byte
  uint64_t message_id1 = 0;    // 1 byte
  rtc::CopyOnWriteBuffer header1;
  webrtc::WriteQuicDataChannelMessageHeader(data_channel_id1, message_id1,
                                            &header1);
  EXPECT_EQ(2u, header1.size());

  int decoded_data_channel_id1;
  uint64_t decoded_message_id1;
  size_t bytes_read1;
  ASSERT_TRUE(webrtc::ParseQuicDataMessageHeader(
      header1.data<char>(), header1.size(), &decoded_data_channel_id1,
      &decoded_message_id1, &bytes_read1));
  EXPECT_EQ(data_channel_id1, decoded_data_channel_id1);
  EXPECT_EQ(message_id1, decoded_message_id1);
  EXPECT_EQ(2u, bytes_read1);

  int data_channel_id2 = 4178;           // 2 bytes
  uint64_t message_id2 = 1324921792003;  // 6 bytes
  rtc::CopyOnWriteBuffer header2;
  webrtc::WriteQuicDataChannelMessageHeader(data_channel_id2, message_id2,
                                            &header2);
  EXPECT_EQ(8u, header2.size());

  int decoded_data_channel_id2;
  uint64_t decoded_message_id2;
  size_t bytes_read2;
  ASSERT_TRUE(webrtc::ParseQuicDataMessageHeader(
      header2.data<char>(), header2.size(), &decoded_data_channel_id2,
      &decoded_message_id2, &bytes_read2));
  EXPECT_EQ(data_channel_id2, decoded_data_channel_id2);
  EXPECT_EQ(message_id2, decoded_message_id2);
  EXPECT_EQ(8u, bytes_read2);
}

}  // namespace
