/*
 *  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 "pc/quicdatachannel.h"

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

#include "p2p/base/faketransportcontroller.h"
#include "p2p/quic/quictransportchannel.h"
#include "p2p/quic/reliablequicstream.h"
#include "rtc_base/bind.h"
#include "rtc_base/gunit.h"
#include "rtc_base/scoped_ref_ptr.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
