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

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

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