// Copyright 2020 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.

#include "third_party/blink/renderer/modules/mediastream/media_stream_video_track_underlying_sink.h"

#include "base/memory/scoped_refptr.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame.h"
#include "third_party/blink/renderer/core/streams/writable_stream.h"
#include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.h"
#include "third_party/blink/renderer/modules/mediastream/pushable_media_stream_video_source.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"

using testing::_;

namespace blink {

class MediaStreamVideoTrackUnderlyingSinkTest : public testing::Test {
 public:
  MediaStreamVideoTrackUnderlyingSinkTest() {
    pushable_video_source_ = new PushableMediaStreamVideoSource();
    media_stream_source_ = MakeGarbageCollected<MediaStreamSource>(
        "dummy_source_id", MediaStreamSource::kTypeVideo, "dummy_source_name",
        /*remote=*/false);
    media_stream_source_->SetPlatformSource(
        base::WrapUnique(pushable_video_source_));
  }

  ~MediaStreamVideoTrackUnderlyingSinkTest() override {
    platform_->RunUntilIdle();
    WebHeap::CollectAllGarbageForTesting();
  }

  MediaStreamVideoTrackUnderlyingSink* CreateUnderlyingSink(
      ScriptState* script_state) {
    return MakeGarbageCollected<MediaStreamVideoTrackUnderlyingSink>(
        pushable_video_source_);
  }

  WebMediaStreamTrack CreateTrack() {
    return MediaStreamVideoTrack::CreateVideoTrack(
        pushable_video_source_,
        MediaStreamVideoSource::ConstraintsOnceCallback(),
        /*enabled=*/true);
  }

  ScriptValue CreateVideoFrameChunk(ScriptState* script_state,
                                    VideoFrame** video_frame_out = nullptr) {
    const scoped_refptr<media::VideoFrame> media_frame =
        media::VideoFrame::CreateBlackFrame(gfx::Size(100, 50));
    VideoFrame* video_frame = MakeGarbageCollected<VideoFrame>(
        std::move(media_frame), ExecutionContext::From(script_state));
    if (video_frame_out)
      *video_frame_out = video_frame;
    return ScriptValue(script_state->GetIsolate(),
                       ToV8(video_frame, script_state->GetContext()->Global(),
                            script_state->GetIsolate()));
  }

 protected:
  ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
  Persistent<MediaStreamSource> media_stream_source_;
  PushableMediaStreamVideoSource* pushable_video_source_;
};

// TODO(1153092): Test flakes, likely due to completing before background
// thread has had chance to call OnVideoFrame().
TEST_F(MediaStreamVideoTrackUnderlyingSinkTest,
       DISABLED_WriteToStreamForwardsToMediaStreamSink) {
  V8TestingScope v8_scope;
  ScriptState* script_state = v8_scope.GetScriptState();
  auto* underlying_sink = CreateUnderlyingSink(script_state);
  auto* writable_stream = WritableStream::CreateWithCountQueueingStrategy(
      script_state, underlying_sink, 1u);

  auto track = CreateTrack();
  MockMediaStreamVideoSink media_stream_video_sink;
  media_stream_video_sink.ConnectToTrack(track);

  NonThrowableExceptionState exception_state;
  auto* writer = writable_stream->getWriter(script_state, exception_state);

  VideoFrame* video_frame = nullptr;
  auto video_frame_chunk = CreateVideoFrameChunk(script_state, &video_frame);
  EXPECT_NE(video_frame, nullptr);
  EXPECT_NE(video_frame->frame(), nullptr);
  EXPECT_CALL(media_stream_video_sink, OnVideoFrame(_));
  ScriptPromiseTester write_tester(
      script_state,
      writer->write(script_state, video_frame_chunk, exception_state));
  write_tester.WaitUntilSettled();
  // |video_frame| should be invalidated after sending it to the sink.
  EXPECT_EQ(video_frame->frame(), nullptr);

  writer->releaseLock(script_state);
  ScriptPromiseTester close_tester(
      script_state, writable_stream->close(script_state, exception_state));
  close_tester.WaitUntilSettled();

  // Writing to the sink after the stream closes should fail.
  DummyExceptionStateForTesting dummy_exception_state;
  underlying_sink->write(script_state, CreateVideoFrameChunk(script_state),
                         nullptr, dummy_exception_state);
  EXPECT_TRUE(dummy_exception_state.HadException());
  EXPECT_EQ(dummy_exception_state.Code(),
            static_cast<ExceptionCode>(DOMExceptionCode::kInvalidStateError));
}

TEST_F(MediaStreamVideoTrackUnderlyingSinkTest, WriteInvalidDataFails) {
  V8TestingScope v8_scope;
  ScriptState* script_state = v8_scope.GetScriptState();
  auto* sink = CreateUnderlyingSink(script_state);
  ScriptValue v8_integer = ScriptValue::From(script_state, 0);

  // Writing something that is not a VideoFrame to the sink should fail.
  DummyExceptionStateForTesting dummy_exception_state;
  sink->write(script_state, v8_integer, nullptr, dummy_exception_state);
  EXPECT_TRUE(dummy_exception_state.HadException());

  // Writing a null value to the sink should fail.
  dummy_exception_state.ClearException();
  EXPECT_FALSE(dummy_exception_state.HadException());
  sink->write(script_state, ScriptValue::CreateNull(v8_scope.GetIsolate()),
              nullptr, dummy_exception_state);
  EXPECT_TRUE(dummy_exception_state.HadException());

  // Writing a destroyed VideoFrame to the sink should fail.
  dummy_exception_state.ClearException();
  VideoFrame* video_frame = nullptr;
  auto chunk = CreateVideoFrameChunk(script_state, &video_frame);
  video_frame->close();
  EXPECT_FALSE(dummy_exception_state.HadException());
  sink->write(script_state, chunk, nullptr, dummy_exception_state);
  EXPECT_TRUE(dummy_exception_state.HadException());
}

TEST_F(MediaStreamVideoTrackUnderlyingSinkTest, WriteToAbortedSinkFails) {
  V8TestingScope v8_scope;
  ScriptState* script_state = v8_scope.GetScriptState();
  auto* underlying_sink = CreateUnderlyingSink(script_state);
  auto* writable_stream = WritableStream::CreateWithCountQueueingStrategy(
      script_state, underlying_sink, 1u);

  NonThrowableExceptionState exception_state;
  ScriptPromiseTester abort_tester(
      script_state, writable_stream->abort(script_state, exception_state));
  abort_tester.WaitUntilSettled();

  // Writing to the sink after the stream closes should fail.
  DummyExceptionStateForTesting dummy_exception_state;
  underlying_sink->write(script_state, CreateVideoFrameChunk(script_state),
                         nullptr, dummy_exception_state);
  EXPECT_TRUE(dummy_exception_state.HadException());
  EXPECT_EQ(dummy_exception_state.Code(),
            static_cast<ExceptionCode>(DOMExceptionCode::kInvalidStateError));
}

}  // namespace blink
