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

#include "storage/browser/blob/blob_impl.h"

#include <limits>
#include <memory>
#include <string>
#include <utility>

#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
#include "net/base/net_errors.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace storage {

namespace {

class DataPipeReader : public mojo::DataPipeDrainer::Client {
 public:
  DataPipeReader(std::string* data_out, base::OnceClosure done_callback)
      : data_out_(data_out), done_callback_(std::move(done_callback)) {}

  void OnDataAvailable(const void* data, size_t num_bytes) override {
    data_out_->append(static_cast<const char*>(data), num_bytes);
  }

  void OnDataComplete() override { std::move(done_callback_).Run(); }

 private:
  raw_ptr<std::string> data_out_;
  base::OnceClosure done_callback_;
};

class MockBlobReaderClient : public blink::mojom::BlobReaderClient {
 public:
  void OnCalculatedSize(uint64_t total_size,
                        uint64_t expected_content_size) override {
    total_size_ = total_size;
    expected_content_size_ = expected_content_size;
    calculated_size_ = true;
  }

  void OnComplete(int32_t status, uint64_t data_length) override {
    status_ = static_cast<net::Error>(status);
    data_length_ = data_length;
    completed_ = true;
  }

  bool calculated_size_ = false;
  uint64_t total_size_ = 0;
  uint64_t expected_content_size_ = 0;
  bool completed_ = false;
  net::Error status_ = net::OK;
  uint64_t data_length_ = 0;
};

}  // namespace

class BlobImplTest : public testing::Test {
 public:
  void SetUp() override { context_ = std::make_unique<BlobStorageContext>(); }

  std::unique_ptr<BlobDataHandle> CreateBlobFromString(
      const std::string& uuid,
      const std::string& contents) {
    auto builder = std::make_unique<BlobDataBuilder>(uuid);
    builder->set_content_type("text/plain");
    builder->AppendData(contents);
    return context_->AddFinishedBlob(std::move(builder));
  }

  std::string UUIDFromBlob(blink::mojom::Blob* blob) {
    base::RunLoop loop;
    std::string received_uuid;
    blob->GetInternalUUID(base::BindOnce(
        [](base::OnceClosure quit_closure, std::string* uuid_out,
           const std::string& uuid) {
          *uuid_out = uuid;
          std::move(quit_closure).Run();
        },
        loop.QuitClosure(), &received_uuid));
    loop.Run();
    return received_uuid;
  }

  std::string ReadDataPipe(mojo::ScopedDataPipeConsumerHandle pipe) {
    base::RunLoop loop;
    std::string data;
    DataPipeReader reader(&data, loop.QuitClosure());
    mojo::DataPipeDrainer drainer(&reader, std::move(pipe));
    loop.Run();
    return data;
  }

 protected:
  base::test::TaskEnvironment task_environment_;
  std::unique_ptr<BlobStorageContext> context_;
};

TEST_F(BlobImplTest, GetInternalUUID) {
  const std::string kId = "id";
  auto handle = CreateBlobFromString(kId, "hello world");

  mojo::Remote<blink::mojom::Blob> remote;
  auto blob =
      BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());
  EXPECT_EQ(kId, UUIDFromBlob(blob.get()));
  EXPECT_EQ(kId, UUIDFromBlob(remote.get()));
}

TEST_F(BlobImplTest, CloneAndLifetime) {
  const std::string kId = "id";
  auto handle = CreateBlobFromString(kId, "hello world");

  mojo::Remote<blink::mojom::Blob> remote;
  auto blob =
      BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());
  EXPECT_EQ(kId, UUIDFromBlob(remote.get()));

  // Blob should exist in registry as long as connection is alive.
  EXPECT_TRUE(context_->registry().HasEntry(kId));
  EXPECT_TRUE(blob);

  mojo::Remote<blink::mojom::Blob> clone;
  blob->Clone(clone.BindNewPipeAndPassReceiver());
  EXPECT_EQ(kId, UUIDFromBlob(clone.get()));
  clone.FlushForTesting();

  remote.reset();
  blob->FlushForTesting();
  EXPECT_TRUE(context_->registry().HasEntry(kId));
  EXPECT_TRUE(blob);

  clone.reset();
  blob->FlushForTesting();
  EXPECT_FALSE(context_->registry().HasEntry(kId));
  EXPECT_FALSE(blob);
}

TEST_F(BlobImplTest, ReadAll) {
  const std::string kId = "id";
  const std::string kContents = "hello world";
  auto handle = CreateBlobFromString(kId, kContents);

  mojo::Remote<blink::mojom::Blob> remote;
  BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());

  MockBlobReaderClient client;
  mojo::Receiver<blink::mojom::BlobReaderClient> client_receiver(&client);

  mojo::ScopedDataPipeProducerHandle producer_handle;
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
            MOJO_RESULT_OK);

  remote->ReadAll(std::move(producer_handle),
                  client_receiver.BindNewPipeAndPassRemote());
  std::string received = ReadDataPipe(std::move(consumer_handle));
  EXPECT_EQ(kContents, received);

  client_receiver.FlushForTesting();
  EXPECT_TRUE(client.calculated_size_);
  EXPECT_EQ(kContents.size(), client.total_size_);
  EXPECT_EQ(kContents.size(), client.expected_content_size_);

  EXPECT_TRUE(client.completed_);
  EXPECT_EQ(net::OK, client.status_);
  EXPECT_EQ(kContents.size(), client.data_length_);
}

TEST_F(BlobImplTest, ReadAll_WithoutClient) {
  const std::string kId = "id";
  const std::string kContents = "hello world";
  auto handle = CreateBlobFromString(kId, kContents);

  mojo::Remote<blink::mojom::Blob> remote;
  BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());

  mojo::ScopedDataPipeProducerHandle producer_handle;
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
            MOJO_RESULT_OK);
  remote->ReadAll(std::move(producer_handle), mojo::NullRemote());
  std::string received = ReadDataPipe(std::move(consumer_handle));
  EXPECT_EQ(kContents, received);
}

TEST_F(BlobImplTest, ReadAll_BrokenBlob) {
  const std::string kId = "id";
  auto handle = context_->AddBrokenBlob(
      kId, "", "", BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS);

  mojo::Remote<blink::mojom::Blob> remote;
  BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());

  MockBlobReaderClient client;
  mojo::Receiver<blink::mojom::BlobReaderClient> client_receiver(&client);

  mojo::ScopedDataPipeProducerHandle producer_handle;
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
            MOJO_RESULT_OK);
  remote->ReadAll(std::move(producer_handle),
                  client_receiver.BindNewPipeAndPassRemote());

  std::string received = ReadDataPipe(std::move(consumer_handle));
  EXPECT_EQ("", received);

  client_receiver.FlushForTesting();
  EXPECT_FALSE(client.calculated_size_);
  EXPECT_TRUE(client.completed_);
  EXPECT_EQ(net::ERR_FAILED, client.status_);
  EXPECT_EQ(0u, client.data_length_);
}

TEST_F(BlobImplTest, ReadRange) {
  const std::string kId = "id";
  const std::string kContents = "hello world";
  auto handle = CreateBlobFromString(kId, kContents);

  mojo::Remote<blink::mojom::Blob> remote;
  BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());

  MockBlobReaderClient client;
  mojo::Receiver<blink::mojom::BlobReaderClient> client_receiver(&client);

  mojo::ScopedDataPipeProducerHandle producer_handle;
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
            MOJO_RESULT_OK);
  remote->ReadRange(2, 5, std::move(producer_handle),
                    client_receiver.BindNewPipeAndPassRemote());

  std::string received = ReadDataPipe(std::move(consumer_handle));
  EXPECT_EQ(kContents.substr(2, 5), received);

  client_receiver.FlushForTesting();
  EXPECT_TRUE(client.calculated_size_);
  EXPECT_EQ(kContents.size(), client.total_size_);
  EXPECT_EQ(5u, client.expected_content_size_);

  EXPECT_TRUE(client.completed_);
  EXPECT_EQ(net::OK, client.status_);
  EXPECT_EQ(5u, client.data_length_);
}

TEST_F(BlobImplTest, ReadRange_WithoutClient) {
  const std::string kId = "id";
  const std::string kContents = "hello world";
  auto handle = CreateBlobFromString(kId, kContents);

  mojo::Remote<blink::mojom::Blob> remote;
  BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());

  mojo::ScopedDataPipeProducerHandle producer_handle;
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
            MOJO_RESULT_OK);
  remote->ReadRange(2, 5, std::move(producer_handle), mojo::NullRemote());

  std::string received = ReadDataPipe(std::move(consumer_handle));
  EXPECT_EQ(kContents.substr(2, 5), received);
}

TEST_F(BlobImplTest, ReadRange_TooLargeLength) {
  const std::string kId = "id";
  const std::string kContents = "hello world";
  auto handle = CreateBlobFromString(kId, kContents);

  mojo::Remote<blink::mojom::Blob> remote;
  BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());

  MockBlobReaderClient client;
  mojo::Receiver<blink::mojom::BlobReaderClient> client_receiver(&client);

  mojo::ScopedDataPipeProducerHandle producer_handle;
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
            MOJO_RESULT_OK);
  remote->ReadRange(2, 15, std::move(producer_handle),
                    client_receiver.BindNewPipeAndPassRemote());

  std::string received = ReadDataPipe(std::move(consumer_handle));
  EXPECT_EQ(kContents.substr(2, 15), received);

  client_receiver.FlushForTesting();
  EXPECT_TRUE(client.calculated_size_);
  EXPECT_EQ(kContents.size(), client.total_size_);
  EXPECT_EQ(kContents.size() - 2, client.expected_content_size_);

  EXPECT_TRUE(client.completed_);
  EXPECT_EQ(net::OK, client.status_);
  EXPECT_EQ(kContents.size() - 2, client.data_length_);
}

TEST_F(BlobImplTest, ReadRange_UnboundedLength) {
  const std::string kId = "id";
  const std::string kContents = "hello world";
  auto handle = CreateBlobFromString(kId, kContents);

  mojo::Remote<blink::mojom::Blob> remote;
  BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());

  MockBlobReaderClient client;
  mojo::Receiver<blink::mojom::BlobReaderClient> client_receiver(&client);

  mojo::ScopedDataPipeProducerHandle producer_handle;
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
            MOJO_RESULT_OK);
  remote->ReadRange(2, std::numeric_limits<uint64_t>::max(),
                    std::move(producer_handle),
                    client_receiver.BindNewPipeAndPassRemote());

  std::string received = ReadDataPipe(std::move(consumer_handle));
  EXPECT_EQ(kContents.substr(2, kContents.size()), received);

  client_receiver.FlushForTesting();
  EXPECT_TRUE(client.calculated_size_);
  EXPECT_EQ(kContents.size(), client.total_size_);
  EXPECT_EQ(kContents.size() - 2, client.expected_content_size_);

  EXPECT_TRUE(client.completed_);
  EXPECT_EQ(net::OK, client.status_);
  EXPECT_EQ(kContents.size() - 2, client.data_length_);
}

TEST_F(BlobImplTest, ReadRange_BrokenBlob) {
  const std::string kId = "id";
  auto handle = context_->AddBrokenBlob(
      kId, "", "", BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS);

  mojo::Remote<blink::mojom::Blob> remote;
  BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());

  MockBlobReaderClient client;
  mojo::Receiver<blink::mojom::BlobReaderClient> client_receiver(&client);

  mojo::ScopedDataPipeProducerHandle producer_handle;
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
            MOJO_RESULT_OK);
  remote->ReadRange(2, 5, std::move(producer_handle),
                    client_receiver.BindNewPipeAndPassRemote());

  std::string received = ReadDataPipe(std::move(consumer_handle));
  EXPECT_EQ("", received);

  client_receiver.FlushForTesting();
  EXPECT_FALSE(client.calculated_size_);
  EXPECT_TRUE(client.completed_);
  EXPECT_EQ(net::ERR_FAILED, client.status_);
  EXPECT_EQ(0u, client.data_length_);
}

TEST_F(BlobImplTest, ReadRange_InvalidRange) {
  const std::string kId = "id";
  const std::string kContents = "hello world";
  auto handle = CreateBlobFromString(kId, kContents);

  mojo::Remote<blink::mojom::Blob> remote;
  BlobImpl::Create(std::move(handle), remote.BindNewPipeAndPassReceiver());

  MockBlobReaderClient client;
  mojo::Receiver<blink::mojom::BlobReaderClient> client_receiver(&client);

  base::RunLoop loop;
  mojo::ScopedDataPipeProducerHandle producer_handle;
  mojo::ScopedDataPipeConsumerHandle consumer_handle;
  ASSERT_EQ(mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle),
            MOJO_RESULT_OK);
  remote->ReadRange(15, 4, std::move(producer_handle),
                    client_receiver.BindNewPipeAndPassRemote());

  std::string received = ReadDataPipe(std::move(consumer_handle));
  EXPECT_EQ("", received);

  client_receiver.FlushForTesting();
  EXPECT_FALSE(client.calculated_size_);
  EXPECT_TRUE(client.completed_);
  EXPECT_EQ(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, client.status_);
  EXPECT_EQ(0u, client.data_length_);
}

}  // namespace storage
