// Copyright 2021 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/video_track_signal_underlying_sink.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/to_v8_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track_signal.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_track.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_component.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 VideoTrackSignalUnderlyingSinkTest : public testing::Test {
 public:
  VideoTrackSignalUnderlyingSinkTest() {
    mock_video_source_ = new MockMediaStreamVideoSource();
    media_stream_source_ = MakeGarbageCollected<MediaStreamSource>(
        "dummy_source_id", MediaStreamSource::kTypeVideo, "dummy_source_name",
        /*remote=*/false);
    media_stream_source_->SetPlatformSource(
        base::WrapUnique(mock_video_source_));
    web_track_ = MediaStreamVideoTrack::CreateVideoTrack(
        mock_video_source_, MediaStreamVideoSource::ConstraintsOnceCallback(),
        true);
    mock_video_source_->StartMockedSource();
  }

  ~VideoTrackSignalUnderlyingSinkTest() override {
    platform_->RunUntilIdle();
    mock_video_source_->StopSource();
    base::RunLoop run_loop;
    platform_->GetIOTaskRunner()->PostTask(FROM_HERE, run_loop.QuitClosure());
    run_loop.Run();
    WebHeap::CollectAllGarbageForTesting();
  }

  MediaStreamTrack* CreateTrack(ExecutionContext* context) const {
    return MakeGarbageCollected<MediaStreamTrack>(context, web_track_);
  }
  VideoTrackSignalUnderlyingSink* CreateUnderlyingSink(
      MediaStreamTrack* track) {
    return MakeGarbageCollected<VideoTrackSignalUnderlyingSink>(track);
  }

  ScriptValue CreateSignalChunk(ScriptState* script_state,
                                const String& signal_name) {
    MediaStreamTrackSignal* signal = MediaStreamTrackSignal::Create();
    signal->setSignalType(signal_name);
    return ScriptValue(script_state->GetIsolate(),
                       ToV8(signal, script_state->GetContext()->Global(),
                            script_state->GetIsolate()));
  }

  ScriptValue CreateRequestFrameChunk(ScriptState* script_state) {
    return CreateSignalChunk(script_state, "request-frame");
  }

  ScriptValue CreateSetMinFrameRateChunk(
      ScriptState* script_state,
      const base::Optional<double>& frame_rate = 10.0) {
    MediaStreamTrackSignal* signal = MediaStreamTrackSignal::Create();
    signal->setSignalType("set-min-frame-rate");
    if (frame_rate)
      signal->setFrameRate(*frame_rate);
    return ScriptValue(script_state->GetIsolate(),
                       ToV8(signal, script_state->GetContext()->Global(),
                            script_state->GetIsolate()));
  }

 protected:
  Persistent<MediaStreamSource> media_stream_source_;
  WebMediaStreamTrack web_track_;
  MockMediaStreamVideoSource* mock_video_source_;
  ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
};

TEST_F(VideoTrackSignalUnderlyingSinkTest,
       WriteRequestFrameToStreamForwardsToVideoSource) {
  V8TestingScope v8_scope;
  ScriptState* script_state = v8_scope.GetScriptState();
  auto* track = CreateTrack(v8_scope.GetExecutionContext());
  auto* underlying_sink = CreateUnderlyingSink(track);
  auto* writable_stream = WritableStream::CreateWithCountQueueingStrategy(
      script_state, underlying_sink, 1u);

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

  auto request_frame_chunk = CreateRequestFrameChunk(script_state);
  EXPECT_CALL(*mock_video_source_, OnRequestRefreshFrame());
  ScriptPromiseTester write_tester(
      script_state,
      writer->write(script_state, request_frame_chunk, exception_state));
  write_tester.WaitUntilSettled();

  const double frame_rate = 14.8;
  auto set_min_frame_rate_chunk =
      CreateSetMinFrameRateChunk(script_state, frame_rate);
  MediaStreamVideoTrack* video_track =
      MediaStreamVideoTrack::From(track->Component());
  EXPECT_FALSE(video_track->min_frame_rate().has_value());
  ScriptPromiseTester write_tester2(
      script_state,
      writer->write(script_state, set_min_frame_rate_chunk, exception_state));
  write_tester2.WaitUntilSettled();
  EXPECT_TRUE(video_track->min_frame_rate().has_value());
  EXPECT_EQ(video_track->min_frame_rate().value(), frame_rate);

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

  MediaStreamTrack* clone = track->clone(script_state);
  track->stopTrack(v8_scope.GetExecutionContext());

  // Writing to the sink after the track closes should fail, even if the source
  // is active.
  EXPECT_TRUE(mock_video_source_->IsRunning());
  DummyExceptionStateForTesting dummy_exception_state;
  underlying_sink->write(script_state, CreateRequestFrameChunk(script_state),
                         nullptr, dummy_exception_state);
  EXPECT_TRUE(dummy_exception_state.HadException());
  EXPECT_EQ(dummy_exception_state.Code(),
            static_cast<ExceptionCode>(DOMExceptionCode::kInvalidStateError));

  clone->stopTrack(v8_scope.GetExecutionContext());
  EXPECT_FALSE(mock_video_source_->IsRunning());
  // Writing to the sink after the source closes should fail.
  dummy_exception_state.ClearException();
  underlying_sink->write(script_state, CreateRequestFrameChunk(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(VideoTrackSignalUnderlyingSinkTest, WriteInvalidDataFails) {
  V8TestingScope v8_scope;
  ScriptState* script_state = v8_scope.GetScriptState();
  auto* track = CreateTrack(v8_scope.GetExecutionContext());
  auto* underlying_sink = CreateUnderlyingSink(track);

  MediaStreamVideoTrack* video_track =
      MediaStreamVideoTrack::From(track->Component());
  EXPECT_FALSE(video_track->min_frame_rate().has_value());

  DummyExceptionStateForTesting exception_state;
  auto set_min_frame_rate_chunk =
      CreateSetMinFrameRateChunk(script_state, base::nullopt);
  underlying_sink->write(script_state, set_min_frame_rate_chunk, nullptr,
                         exception_state);
  EXPECT_TRUE(exception_state.HadException());
  EXPECT_FALSE(video_track->min_frame_rate().has_value());

  exception_state.ClearException();
  EXPECT_FALSE(exception_state.HadException());
  underlying_sink->write(script_state,
                         CreateSignalChunk(script_state, "invalid-signal"),
                         nullptr, exception_state);
  EXPECT_TRUE(exception_state.HadException());

  // Writing null fails
  exception_state.ClearException();
  EXPECT_FALSE(exception_state.HadException());
  underlying_sink->write(script_state,
                         ScriptValue::CreateNull(v8_scope.GetIsolate()),
                         nullptr, exception_state);
  EXPECT_TRUE(exception_state.HadException());

  // Writing an intenger fails
  exception_state.ClearException();
  EXPECT_FALSE(exception_state.HadException());
  underlying_sink->write(script_state, ScriptValue::From(script_state, 5),
                         nullptr, exception_state);
  EXPECT_TRUE(exception_state.HadException());

  track->stopTrack(v8_scope.GetExecutionContext());
}

TEST_F(VideoTrackSignalUnderlyingSinkTest, WriteToClosedSinkFails) {
  V8TestingScope v8_scope;
  ScriptState* script_state = v8_scope.GetScriptState();
  auto* track = CreateTrack(v8_scope.GetExecutionContext());
  auto* underlying_sink = CreateUnderlyingSink(track);

  auto* writable_stream = WritableStream::CreateWithCountQueueingStrategy(
      script_state, underlying_sink, 1u);

  NonThrowableExceptionState exception_state;
  ScriptPromiseTester abort_tester(
      script_state, writable_stream->close(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, CreateRequestFrameChunk(script_state),
                         nullptr, dummy_exception_state);
  EXPECT_TRUE(dummy_exception_state.HadException());
  EXPECT_EQ(dummy_exception_state.Code(),
            static_cast<ExceptionCode>(DOMExceptionCode::kInvalidStateError));

  track->stopTrack(v8_scope.GetExecutionContext());
}

TEST_F(VideoTrackSignalUnderlyingSinkTest, WriteToAbortedSinkFails) {
  V8TestingScope v8_scope;
  ScriptState* script_state = v8_scope.GetScriptState();
  auto* track = CreateTrack(v8_scope.GetExecutionContext());
  auto* underlying_sink = CreateUnderlyingSink(track);

  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 aborts should fail.
  DummyExceptionStateForTesting dummy_exception_state;
  underlying_sink->write(script_state, CreateRequestFrameChunk(script_state),
                         nullptr, dummy_exception_state);
  EXPECT_TRUE(dummy_exception_state.HadException());
  EXPECT_EQ(dummy_exception_state.Code(),
            static_cast<ExceptionCode>(DOMExceptionCode::kInvalidStateError));

  track->stopTrack(v8_scope.GetExecutionContext());
}

}  // namespace blink
