/*
 *  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(), 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_->Connect();
    other_peer->ice_transport_channel_->Connect();
    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
