// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file tests the RTCQuicStream Blink bindings, QuicStreamProxy and
// QuicStreamHost by mocking out the underlying P2PQuicTransport.
// Everything is run on a single thread but with separate TestSimpleTaskRunners
// for the main thread / worker thread.

#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_p2p_quic_stream.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.h"

namespace blink {
namespace {

using testing::_;
using testing::ElementsAre;
using testing::InvokeWithoutArgs;
using testing::Return;
using testing::SaveArg;

NotShared<DOMUint8Array> CreateUint8Array(const Vector<uint8_t>& data) {
  return NotShared<DOMUint8Array>(
      DOMUint8Array::Create(data.data(), data.size()));
}

NotShared<DOMUint8Array> CreateUint8ArrayOfLength(uint32_t length) {
  return NotShared<DOMUint8Array>(DOMUint8Array::Create(length));
}

}  // namespace

class RTCQuicStreamTest : public RTCQuicTransportTest {
 public:
  RTCQuicStream* CreateQuicStream(V8TestingScope& scope,
                                  MockP2PQuicStream* mock_stream) {
    auto p2p_quic_transport = std::make_unique<MockP2PQuicTransport>();
    EXPECT_CALL(*p2p_quic_transport, CreateStream())
        .WillOnce(Return(mock_stream));
    Persistent<RTCQuicTransport> quic_transport =
        CreateConnectedQuicTransport(scope, std::move(p2p_quic_transport));
    return quic_transport->createStream(ASSERT_NO_EXCEPTION);
  }
};

// Test that RTCQuicTransport.createStream causes CreateStream to be called on
// the underlying transport and a P2PQuicStream::Delegate to be set on the
// underlying P2PQuicStream.
TEST_F(RTCQuicStreamTest, RTCQuicTransportCreateStreamCallsUnderlying) {
  V8TestingScope scope;

  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>();
  EXPECT_CALL(*p2p_quic_stream, SetDelegate(_))
      .WillOnce(testing::Invoke(
          [](P2PQuicStream::Delegate* delegate) { EXPECT_TRUE(delegate); }));

  auto p2p_quic_transport = std::make_unique<MockP2PQuicTransport>();
  EXPECT_CALL(*p2p_quic_transport, CreateStream())
      .WillOnce(Return(p2p_quic_stream.get()));

  Persistent<RTCQuicTransport> quic_transport =
      CreateConnectedQuicTransport(scope, std::move(p2p_quic_transport));
  Persistent<RTCQuicStream> quic_stream =
      quic_transport->createStream(ASSERT_NO_EXCEPTION);

  RunUntilIdle();
}

// Test that calling OnStream on the P2PQuicTransport delegate causes a
// quicstream event to fire with a new RTCQuicStream.
TEST_F(RTCQuicStreamTest, NewRemoteStreamFiresEvent) {
  V8TestingScope scope;

  P2PQuicTransport::Delegate* transport_delegate = nullptr;
  Persistent<RTCQuicTransport> quic_transport =
      CreateConnectedQuicTransport(scope, &transport_delegate);

  Persistent<MockEventListener> quic_stream_listener =
      CreateMockEventListener();
  EXPECT_CALL(*quic_stream_listener, Invoke(_, _))
      .WillOnce(testing::Invoke([](ExecutionContext*, Event* event) {
        auto* stream_event = static_cast<RTCQuicStreamEvent*>(event);
        EXPECT_NE(nullptr, stream_event->stream());
      }));
  quic_transport->addEventListener(event_type_names::kQuicstream,
                                   quic_stream_listener);

  ASSERT_TRUE(transport_delegate);

  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>();
  EXPECT_CALL(*p2p_quic_stream, SetDelegate(_))
      .WillOnce(testing::Invoke(
          [](P2PQuicStream::Delegate* delegate) { EXPECT_TRUE(delegate); }));
  transport_delegate->OnStream(p2p_quic_stream.get());

  RunUntilIdle();
}

// Test that calling reset() calls Reset() on the underlying P2PQuicStream.
TEST_F(RTCQuicStreamTest, ResetCallsUnderlying) {
  V8TestingScope scope;

  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>();
  EXPECT_CALL(*p2p_quic_stream, Reset()).Times(1);

  auto p2p_quic_transport = std::make_unique<MockP2PQuicTransport>();
  EXPECT_CALL(*p2p_quic_transport, CreateStream())
      .WillOnce(Return(p2p_quic_stream.get()));

  Persistent<RTCQuicTransport> quic_transport =
      CreateConnectedQuicTransport(scope, std::move(p2p_quic_transport));
  Persistent<RTCQuicStream> stream =
      quic_transport->createStream(ASSERT_NO_EXCEPTION);

  stream->reset();

  RunUntilIdle();
}

// Test that calling OnRemoteReset() on the P2PQuicStream delegate fires a
// statechange event to 'closed'.
TEST_F(RTCQuicStreamTest, OnRemoteResetFiresStateChangeToClosed) {
  V8TestingScope scope;

  P2PQuicStream::Delegate* stream_delegate = nullptr;
  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>();
  EXPECT_CALL(*p2p_quic_stream, SetDelegate(_))
      .WillOnce(SaveArg<0>(&stream_delegate));

  auto p2p_quic_transport = std::make_unique<MockP2PQuicTransport>();
  EXPECT_CALL(*p2p_quic_transport, CreateStream())
      .WillOnce(Return(p2p_quic_stream.get()));

  Persistent<RTCQuicTransport> quic_transport =
      CreateConnectedQuicTransport(scope, std::move(p2p_quic_transport));
  Persistent<RTCQuicStream> quic_stream =
      quic_transport->createStream(ASSERT_NO_EXCEPTION);

  Persistent<MockEventListener> state_change_listener =
      CreateMockEventListener();
  EXPECT_CALL(*state_change_listener, Invoke(_, _))
      .WillOnce(InvokeWithoutArgs(
          [quic_stream]() { EXPECT_EQ("closed", quic_stream->state()); }));
  quic_stream->addEventListener(event_type_names::kStatechange,
                                state_change_listener);

  RunUntilIdle();

  ASSERT_TRUE(stream_delegate);
  stream_delegate->OnRemoteReset();

  RunUntilIdle();
}

// Test that a pending OnRemoteReset() is ignored if reset() is called first.
TEST_F(RTCQuicStreamTest, PendingOnRemoteResetIgnoredAfterReset) {
  V8TestingScope scope;

  P2PQuicStream::Delegate* stream_delegate = nullptr;
  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>();
  EXPECT_CALL(*p2p_quic_stream, SetDelegate(_))
      .WillOnce(SaveArg<0>(&stream_delegate));

  auto p2p_quic_transport = std::make_unique<MockP2PQuicTransport>();
  EXPECT_CALL(*p2p_quic_transport, CreateStream())
      .WillOnce(Return(p2p_quic_stream.get()));

  Persistent<RTCQuicTransport> quic_transport =
      CreateConnectedQuicTransport(scope, std::move(p2p_quic_transport));
  Persistent<RTCQuicStream> quic_stream =
      quic_transport->createStream(ASSERT_NO_EXCEPTION);

  // Expect no statechange event since reset() will already transition the state
  // to 'closed'.
  Persistent<MockEventListener> state_change_listener =
      CreateMockEventListener();
  EXPECT_CALL(*state_change_listener, Invoke(_, _)).Times(0);
  quic_stream->addEventListener(event_type_names::kStatechange,
                                state_change_listener);

  RunUntilIdle();

  ASSERT_TRUE(stream_delegate);
  stream_delegate->OnRemoteReset();
  quic_stream->reset();
  EXPECT_EQ("closed", quic_stream->state());

  RunUntilIdle();

  EXPECT_EQ("closed", quic_stream->state());
}

// The following group tests write(), finish(), writeBufferedAmount(), and
// maxWriteBufferdAmount().

// Test that write() adds to writeBufferedAmount().
TEST_F(RTCQuicStreamTest, WriteAddsToWriteBufferedAmount) {
  V8TestingScope scope;

  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>();
  Persistent<RTCQuicStream> stream =
      CreateQuicStream(scope, p2p_quic_stream.get());

  stream->write(CreateUint8Array({1, 2}), ASSERT_NO_EXCEPTION);
  EXPECT_EQ(2u, stream->writeBufferedAmount());

  stream->write(CreateUint8Array({3, 4, 5}), ASSERT_NO_EXCEPTION);
  EXPECT_EQ(5u, stream->writeBufferedAmount());

  RunUntilIdle();
}

// Test that write() calls WriteData() on the underlying P2PQuicStream.
TEST_F(RTCQuicStreamTest, WriteCallsWriteData) {
  V8TestingScope scope;

  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>();
  EXPECT_CALL(*p2p_quic_stream, WriteData(_, _))
      .WillOnce(testing::Invoke([](Vector<uint8_t> data, bool fin) {
        EXPECT_THAT(data, ElementsAre(1, 2, 3, 4));
        EXPECT_FALSE(fin);
      }));

  Persistent<RTCQuicStream> stream =
      CreateQuicStream(scope, p2p_quic_stream.get());
  stream->write(CreateUint8Array({1, 2, 3, 4}), ASSERT_NO_EXCEPTION);

  RunUntilIdle();
}

// Test that write() with no data succeeds but does not post a WriteData() to
// the underlying P2PQuicStream.
TEST_F(RTCQuicStreamTest, WriteWithEmptyArrayDoesNotCallWriteData) {
  V8TestingScope scope;

  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>();
  EXPECT_CALL(*p2p_quic_stream, WriteData(_, _)).Times(0);

  Persistent<RTCQuicStream> stream =
      CreateQuicStream(scope, p2p_quic_stream.get());
  stream->write(CreateUint8Array({}), ASSERT_NO_EXCEPTION);

  RunUntilIdle();
}

// Test that finish() calls WriteData() on the underlying P2PQuicStream.
TEST_F(RTCQuicStreamTest, FinishCallsWriteData) {
  V8TestingScope scope;

  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>();
  EXPECT_CALL(*p2p_quic_stream, WriteData(_, _))
      .WillOnce(testing::Invoke([](Vector<uint8_t> data, bool fin) {
        EXPECT_THAT(data, ElementsAre());
        EXPECT_TRUE(fin);
      }));

  Persistent<RTCQuicStream> stream =
      CreateQuicStream(scope, p2p_quic_stream.get());
  stream->finish();

  RunUntilIdle();
}

// Test that writeBufferedAmount is decreased when receiving OnWriteDataConsumed
// from the underlying P2PQuicStream.
TEST_F(RTCQuicStreamTest, OnWriteDataConsumedSubtractsFromWriteBufferedAmount) {
  V8TestingScope scope;

  P2PQuicStream::Delegate* stream_delegate = nullptr;
  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>(&stream_delegate);

  Persistent<RTCQuicStream> stream =
      CreateQuicStream(scope, p2p_quic_stream.get());
  stream->write(CreateUint8ArrayOfLength(4), ASSERT_NO_EXCEPTION);

  RunUntilIdle();

  ASSERT_TRUE(stream_delegate);
  stream_delegate->OnWriteDataConsumed(4);

  RunUntilIdle();

  EXPECT_EQ(0u, stream->writeBufferedAmount());
}

// Test that writeBufferedAmount is set to 0 if the stream was reset by the
// remote peer.
TEST_F(RTCQuicStreamTest, OnRemoteResetSetsWriteBufferedAmountToZero) {
  V8TestingScope scope;

  P2PQuicStream::Delegate* stream_delegate = nullptr;
  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>(&stream_delegate);

  Persistent<RTCQuicStream> stream =
      CreateQuicStream(scope, p2p_quic_stream.get());
  stream->write(CreateUint8ArrayOfLength(4), ASSERT_NO_EXCEPTION);

  RunUntilIdle();

  ASSERT_TRUE(stream_delegate);
  stream_delegate->OnRemoteReset();

  RunUntilIdle();

  EXPECT_EQ(0u, stream->writeBufferedAmount());

  RunUntilIdle();
}

// Test that write throws an InvalidStateError if the stream was reset by the
// remote peer.
TEST_F(RTCQuicStreamTest, WriteThrowsIfRemoteReset) {
  V8TestingScope scope;

  P2PQuicStream::Delegate* stream_delegate = nullptr;
  auto p2p_quic_stream = std::make_unique<MockP2PQuicStream>(&stream_delegate);

  Persistent<RTCQuicStream> stream =
      CreateQuicStream(scope, p2p_quic_stream.get());

  RunUntilIdle();

  ASSERT_TRUE(stream_delegate);
  stream_delegate->OnRemoteReset();

  RunUntilIdle();

  stream->write(CreateUint8ArrayOfLength(1), scope.GetExceptionState());
  EXPECT_EQ(DOMExceptionCode::kInvalidStateError,
            scope.GetExceptionState().CodeAs<DOMExceptionCode>());

  RunUntilIdle();
}

}  // namespace blink
