// Copyright 2014 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 "core/fetch/BodyStreamBuffer.h"

#include <memory>
#include "bindings/core/v8/V8BindingForTesting.h"
#include "core/dom/Document.h"
#include "core/fetch/BlobBytesConsumer.h"
#include "core/fetch/BytesConsumerTestUtil.h"
#include "core/fetch/FormDataBytesConsumer.h"
#include "core/html/forms/FormData.h"
#include "platform/blob/BlobData.h"
#include "platform/blob/BlobURL.h"
#include "platform/network/EncodedFormData.h"
#include "platform/testing/UnitTestHelpers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace blink {

namespace {

using ::testing::ByMove;
using ::testing::InSequence;
using ::testing::Return;
using ::testing::_;
using ::testing::SaveArg;
using Checkpoint = ::testing::StrictMock<::testing::MockFunction<void(int)>>;
using BytesConsumerCommand = BytesConsumerTestUtil::Command;
using ReplayingBytesConsumer = BytesConsumerTestUtil::ReplayingBytesConsumer;
using MockFetchDataLoaderClient =
    BytesConsumerTestUtil::MockFetchDataLoaderClient;

class BodyStreamBufferTest : public ::testing::Test {
 protected:
  ScriptValue Eval(ScriptState* script_state, const char* s) {
    v8::Local<v8::String> source;
    v8::Local<v8::Script> script;
    v8::MicrotasksScope microtasks(script_state->GetIsolate(),
                                   v8::MicrotasksScope::kDoNotRunMicrotasks);
    if (!v8::String::NewFromUtf8(script_state->GetIsolate(), s,
                                 v8::NewStringType::kNormal)
             .ToLocal(&source)) {
      ADD_FAILURE();
      return ScriptValue();
    }
    if (!v8::Script::Compile(script_state->GetContext(), source)
             .ToLocal(&script)) {
      ADD_FAILURE() << "Compilation fails";
      return ScriptValue();
    }
    return ScriptValue(script_state, script->Run(script_state->GetContext()));
  }
  ScriptValue EvalWithPrintingError(ScriptState* script_state, const char* s) {
    v8::TryCatch block(script_state->GetIsolate());
    ScriptValue r = Eval(script_state, s);
    if (block.HasCaught()) {
      ADD_FAILURE() << ToCoreString(block.Exception()->ToString(
                                        script_state->GetIsolate()))
                           .Utf8()
                           .data();
      block.ReThrow();
    }
    return r;
  }
};

TEST_F(BodyStreamBufferTest, Tee) {
  V8TestingScope scope;
  Checkpoint checkpoint;
  MockFetchDataLoaderClient* client1 = MockFetchDataLoaderClient::Create();
  MockFetchDataLoaderClient* client2 = MockFetchDataLoaderClient::Create();

  InSequence s;
  EXPECT_CALL(checkpoint, Call(0));
  EXPECT_CALL(*client1, DidFetchDataLoadedString(String("hello, world")));
  EXPECT_CALL(checkpoint, Call(1));
  EXPECT_CALL(checkpoint, Call(2));
  EXPECT_CALL(*client2, DidFetchDataLoadedString(String("hello, world")));
  EXPECT_CALL(checkpoint, Call(3));
  EXPECT_CALL(checkpoint, Call(4));

  ReplayingBytesConsumer* src =
      new ReplayingBytesConsumer(&scope.GetDocument());
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kData, "hello, "));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kData, "world"));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kDone));
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, nullptr);

  BodyStreamBuffer* new1;
  BodyStreamBuffer* new2;
  buffer->Tee(&new1, &new2);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());

  checkpoint.Call(0);
  new1->StartLoading(FetchDataLoader::CreateLoaderAsString(), client1);
  checkpoint.Call(1);
  testing::RunPendingTasks();
  checkpoint.Call(2);

  new2->StartLoading(FetchDataLoader::CreateLoaderAsString(), client2);
  checkpoint.Call(3);
  testing::RunPendingTasks();
  checkpoint.Call(4);
}

TEST_F(BodyStreamBufferTest, TeeFromHandleMadeFromStream) {
  V8TestingScope scope;
  ScriptValue stream = EvalWithPrintingError(
      scope.GetScriptState(),
      "stream = new ReadableStream({start: c => controller = c});"
      "controller.enqueue(new Uint8Array([0x41, 0x42]));"
      "controller.enqueue(new Uint8Array([0x55, 0x58]));"
      "controller.close();"
      "stream");
  Checkpoint checkpoint;
  MockFetchDataLoaderClient* client1 = MockFetchDataLoaderClient::Create();
  MockFetchDataLoaderClient* client2 = MockFetchDataLoaderClient::Create();

  InSequence s;
  EXPECT_CALL(checkpoint, Call(1));
  EXPECT_CALL(*client1, DidFetchDataLoadedString(String("ABUX")));
  EXPECT_CALL(checkpoint, Call(2));
  EXPECT_CALL(checkpoint, Call(3));
  EXPECT_CALL(*client2, DidFetchDataLoadedString(String("ABUX")));
  EXPECT_CALL(checkpoint, Call(4));

  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), stream);

  BodyStreamBuffer* new1;
  BodyStreamBuffer* new2;
  buffer->Tee(&new1, &new2);

  EXPECT_TRUE(buffer->IsStreamLocked());
  // Note that this behavior is slightly different from for the behavior of
  // a BodyStreamBuffer made from a BytesConsumer. See the above test. In this
  // test, the stream will get disturbed when the microtask is performed.
  // TODO(yhirano): A uniformed behavior is preferred.
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());

  v8::MicrotasksScope::PerformCheckpoint(scope.GetScriptState()->GetIsolate());

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());

  new1->StartLoading(FetchDataLoader::CreateLoaderAsString(), client1);
  checkpoint.Call(1);
  testing::RunPendingTasks();
  checkpoint.Call(2);

  new2->StartLoading(FetchDataLoader::CreateLoaderAsString(), client2);
  checkpoint.Call(3);
  testing::RunPendingTasks();
  checkpoint.Call(4);
}

TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandle) {
  V8TestingScope scope;
  std::unique_ptr<BlobData> data = BlobData::Create();
  data->AppendText("hello", false);
  auto size = data->length();
  scoped_refptr<BlobDataHandle> blob_data_handle =
      BlobDataHandle::Create(std::move(data), size);
  BodyStreamBuffer* buffer = new BodyStreamBuffer(
      scope.GetScriptState(),
      new BlobBytesConsumer(scope.GetExecutionContext(), blob_data_handle),
      nullptr);

  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
  scoped_refptr<BlobDataHandle> output_blob_data_handle =
      buffer->DrainAsBlobDataHandle(
          BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
  EXPECT_EQ(blob_data_handle, output_blob_data_handle);
}

TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandleReturnsNull) {
  V8TestingScope scope;
  // This BytesConsumer is not drainable.
  BytesConsumer* src = new ReplayingBytesConsumer(&scope.GetDocument());
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, nullptr);

  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());

  EXPECT_FALSE(buffer->DrainAsBlobDataHandle(
      BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize));

  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
}

TEST_F(BodyStreamBufferTest,
       DrainAsBlobFromBufferMadeFromBufferMadeFromStream) {
  V8TestingScope scope;
  ScriptValue stream =
      EvalWithPrintingError(scope.GetScriptState(), "new ReadableStream()");
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), stream);

  EXPECT_FALSE(buffer->HasPendingActivity());
  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_TRUE(buffer->IsStreamReadable());

  EXPECT_FALSE(buffer->DrainAsBlobDataHandle(
      BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize));

  EXPECT_FALSE(buffer->HasPendingActivity());
  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_TRUE(buffer->IsStreamReadable());
}

TEST_F(BodyStreamBufferTest, DrainAsFormData) {
  V8TestingScope scope;
  FormData* data = FormData::Create(UTF8Encoding());
  data->append("name1", "value1");
  data->append("name2", "value2");
  scoped_refptr<EncodedFormData> input_form_data =
      data->EncodeMultiPartFormData();

  BodyStreamBuffer* buffer = new BodyStreamBuffer(
      scope.GetScriptState(),
      new FormDataBytesConsumer(scope.GetExecutionContext(), input_form_data),
      nullptr);

  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
  scoped_refptr<EncodedFormData> output_form_data = buffer->DrainAsFormData();

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
  EXPECT_EQ(output_form_data->FlattenToString(),
            input_form_data->FlattenToString());
}

TEST_F(BodyStreamBufferTest, DrainAsFormDataReturnsNull) {
  V8TestingScope scope;
  // This BytesConsumer is not drainable.
  BytesConsumer* src = new ReplayingBytesConsumer(&scope.GetDocument());
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, nullptr);

  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());

  EXPECT_FALSE(buffer->DrainAsFormData());

  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
}

TEST_F(BodyStreamBufferTest,
       DrainAsFormDataFromBufferMadeFromBufferMadeFromStream) {
  V8TestingScope scope;
  ScriptValue stream =
      EvalWithPrintingError(scope.GetScriptState(), "new ReadableStream()");
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), stream);

  EXPECT_FALSE(buffer->HasPendingActivity());
  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_TRUE(buffer->IsStreamReadable());

  EXPECT_FALSE(buffer->DrainAsFormData());

  EXPECT_FALSE(buffer->HasPendingActivity());
  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_TRUE(buffer->IsStreamReadable());
}

TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsArrayBuffer) {
  V8TestingScope scope;
  Checkpoint checkpoint;
  MockFetchDataLoaderClient* client = MockFetchDataLoaderClient::Create();
  DOMArrayBuffer* array_buffer = nullptr;

  InSequence s;
  EXPECT_CALL(checkpoint, Call(1));
  EXPECT_CALL(*client, DidFetchDataLoadedArrayBufferMock(_))
      .WillOnce(SaveArg<0>(&array_buffer));
  EXPECT_CALL(checkpoint, Call(2));

  ReplayingBytesConsumer* src =
      new ReplayingBytesConsumer(&scope.GetDocument());
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kWait));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kData, "hello"));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kDone));
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, nullptr);
  buffer->StartLoading(FetchDataLoader::CreateLoaderAsArrayBuffer(), client);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_TRUE(buffer->HasPendingActivity());

  checkpoint.Call(1);
  testing::RunPendingTasks();
  checkpoint.Call(2);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
  ASSERT_TRUE(array_buffer);
  EXPECT_EQ("hello", String(static_cast<const char*>(array_buffer->Data()),
                            array_buffer->ByteLength()));
}

TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsBlob) {
  V8TestingScope scope;
  Checkpoint checkpoint;
  MockFetchDataLoaderClient* client = MockFetchDataLoaderClient::Create();
  scoped_refptr<BlobDataHandle> blob_data_handle;

  InSequence s;
  EXPECT_CALL(checkpoint, Call(1));
  EXPECT_CALL(*client, DidFetchDataLoadedBlobHandleMock(_))
      .WillOnce(SaveArg<0>(&blob_data_handle));
  EXPECT_CALL(checkpoint, Call(2));

  ReplayingBytesConsumer* src =
      new ReplayingBytesConsumer(&scope.GetDocument());
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kWait));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kData, "hello"));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kDone));
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, nullptr);
  buffer->StartLoading(FetchDataLoader::CreateLoaderAsBlobHandle("text/plain"),
                       client);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_TRUE(buffer->HasPendingActivity());

  checkpoint.Call(1);
  testing::RunPendingTasks();
  checkpoint.Call(2);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
  EXPECT_EQ(5u, blob_data_handle->size());
}

TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsString) {
  V8TestingScope scope;
  Checkpoint checkpoint;
  MockFetchDataLoaderClient* client = MockFetchDataLoaderClient::Create();

  InSequence s;
  EXPECT_CALL(checkpoint, Call(1));
  EXPECT_CALL(*client, DidFetchDataLoadedString(String("hello")));
  EXPECT_CALL(checkpoint, Call(2));

  ReplayingBytesConsumer* src =
      new ReplayingBytesConsumer(&scope.GetDocument());
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kWait));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kData, "hello"));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kDone));
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, nullptr);
  buffer->StartLoading(FetchDataLoader::CreateLoaderAsString(), client);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_TRUE(buffer->HasPendingActivity());

  checkpoint.Call(1);
  testing::RunPendingTasks();
  checkpoint.Call(2);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
}

TEST_F(BodyStreamBufferTest, LoadClosedHandle) {
  V8TestingScope scope;
  Checkpoint checkpoint;
  MockFetchDataLoaderClient* client = MockFetchDataLoaderClient::Create();

  InSequence s;
  EXPECT_CALL(checkpoint, Call(1));
  EXPECT_CALL(*client, DidFetchDataLoadedString(String("")));
  EXPECT_CALL(checkpoint, Call(2));

  BodyStreamBuffer* buffer = new BodyStreamBuffer(
      scope.GetScriptState(), BytesConsumer::CreateClosed(), nullptr);

  EXPECT_TRUE(buffer->IsStreamClosed());

  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());

  checkpoint.Call(1);
  buffer->StartLoading(FetchDataLoader::CreateLoaderAsString(), client);
  checkpoint.Call(2);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
}

TEST_F(BodyStreamBufferTest, LoadErroredHandle) {
  V8TestingScope scope;
  Checkpoint checkpoint;
  MockFetchDataLoaderClient* client = MockFetchDataLoaderClient::Create();

  InSequence s;
  EXPECT_CALL(checkpoint, Call(1));
  EXPECT_CALL(*client, DidFetchDataLoadFailed());
  EXPECT_CALL(checkpoint, Call(2));

  BodyStreamBuffer* buffer = new BodyStreamBuffer(
      scope.GetScriptState(),
      BytesConsumer::CreateErrored(BytesConsumer::Error()), nullptr);

  EXPECT_TRUE(buffer->IsStreamErrored());

  EXPECT_FALSE(buffer->IsStreamLocked());
  EXPECT_FALSE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());

  checkpoint.Call(1);
  buffer->StartLoading(FetchDataLoader::CreateLoaderAsString(), client);
  checkpoint.Call(2);

  EXPECT_TRUE(buffer->IsStreamLocked());
  EXPECT_TRUE(buffer->IsStreamDisturbed());
  EXPECT_FALSE(buffer->HasPendingActivity());
}

TEST_F(BodyStreamBufferTest, LoaderShouldBeKeptAliveByBodyStreamBuffer) {
  V8TestingScope scope;
  Checkpoint checkpoint;
  MockFetchDataLoaderClient* client = MockFetchDataLoaderClient::Create();

  InSequence s;
  EXPECT_CALL(checkpoint, Call(1));
  EXPECT_CALL(*client, DidFetchDataLoadedString(String("hello")));
  EXPECT_CALL(checkpoint, Call(2));

  ReplayingBytesConsumer* src =
      new ReplayingBytesConsumer(&scope.GetDocument());
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kWait));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kData, "hello"));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kDone));
  Persistent<BodyStreamBuffer> buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, nullptr);
  buffer->StartLoading(FetchDataLoader::CreateLoaderAsString(), client);

  ThreadState::Current()->CollectAllGarbage();
  checkpoint.Call(1);
  testing::RunPendingTasks();
  checkpoint.Call(2);
}

TEST_F(BodyStreamBufferTest, SourceShouldBeCanceledWhenCanceled) {
  V8TestingScope scope;
  ReplayingBytesConsumer* consumer =
      new BytesConsumerTestUtil::ReplayingBytesConsumer(
          scope.GetExecutionContext());

  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), consumer, nullptr);
  ScriptValue reason(scope.GetScriptState(),
                     V8String(scope.GetScriptState()->GetIsolate(), "reason"));
  EXPECT_FALSE(consumer->IsCancelled());
  buffer->Cancel(scope.GetScriptState(), reason);
  EXPECT_TRUE(consumer->IsCancelled());
}

TEST_F(BodyStreamBufferTest, NestedPull) {
  V8TestingScope scope;
  ReplayingBytesConsumer* src =
      new ReplayingBytesConsumer(&scope.GetDocument());
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kWait));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kData, "hello"));
  src->Add(BytesConsumerCommand(BytesConsumerCommand::kError));
  Persistent<BodyStreamBuffer> buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, nullptr);

  auto result =
      scope.GetScriptState()->GetContext()->Global()->CreateDataProperty(
          scope.GetScriptState()->GetContext(),
          V8String(scope.GetIsolate(), "stream"), buffer->Stream().V8Value());

  ASSERT_TRUE(result.IsJust());
  ASSERT_TRUE(result.FromJust());

  ScriptValue stream = EvalWithPrintingError(scope.GetScriptState(),
                                             "reader = stream.getReader();");
  ASSERT_FALSE(stream.IsEmpty());

  EvalWithPrintingError(scope.GetScriptState(), "reader.read();");
  EvalWithPrintingError(scope.GetScriptState(), "reader.read();");

  testing::RunPendingTasks();
  v8::MicrotasksScope::PerformCheckpoint(scope.GetScriptState()->GetIsolate());
}

TEST_F(BodyStreamBufferTest, NullAbortSignalIsNotAborted) {
  V8TestingScope scope;
  // This BytesConsumer is not drainable.
  BytesConsumer* src = new ReplayingBytesConsumer(&scope.GetDocument());
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, nullptr);

  EXPECT_FALSE(buffer->IsAborted());
}

TEST_F(BodyStreamBufferTest, AbortSignalMakesAborted) {
  V8TestingScope scope;
  // This BytesConsumer is not drainable.
  BytesConsumer* src = new ReplayingBytesConsumer(&scope.GetDocument());
  auto* signal = new AbortSignal(scope.GetExecutionContext());
  BodyStreamBuffer* buffer =
      new BodyStreamBuffer(scope.GetScriptState(), src, signal);

  EXPECT_FALSE(buffer->IsAborted());
  signal->SignalAbort();
  EXPECT_TRUE(buffer->IsAborted());
}

}  // namespace

}  // namespace blink
