// Copyright 2013 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 "content/browser/fileapi/fileapi_message_filter.h"

#include <string>
#include <vector>

#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/process/process_handle.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
#include "content/browser/streams/stream_registry.h"
#include "content/common/fileapi/file_system_messages.h"
#include "content/common/fileapi/webblob_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/common_param_traits.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_file_system_context.h"
#include "net/base/io_buffer.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/common/data_element.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

namespace {

const char kFakeBlobInternalUrlSpec[] =
    "blob:blobinternal%3A///dc83ede4-9bbd-453b-be2e-60fd623fcc93";
const char kFakeBlobInternalUrlSpec2[] =
    "blob:blobinternal%3A///d28ae2e7-d233-4dda-9598-d135fe5d403e";

const char kFakeContentType[] = "fake/type";

}  // namespace

class FileAPIMessageFilterTest : public testing::Test {
 public:
  FileAPIMessageFilterTest()
      : io_browser_thread_(BrowserThread::IO, &message_loop_) {
  }

 protected:
  void SetUp() override {
    file_system_context_ =
        CreateFileSystemContextForTesting(NULL, base::FilePath());

    std::vector<storage::FileSystemType> types;
    file_system_context_->GetFileSystemTypes(&types);
    for (size_t i = 0; i < types.size(); ++i) {
      ChildProcessSecurityPolicyImpl::GetInstance()
          ->RegisterFileSystemPermissionPolicy(
              types[i],
              storage::FileSystemContext::GetPermissionPolicy(types[i]));
    }

    stream_context_ = StreamContext::GetFor(&browser_context_);
    blob_storage_context_ = ChromeBlobStorageContext::GetFor(&browser_context_);

    filter_ = new FileAPIMessageFilter(
        0 /* process_id */,
        browser_context_.GetRequestContext(),
        file_system_context_.get(),
        blob_storage_context_,
        stream_context_);

    // Complete initialization.
    message_loop_.RunUntilIdle();
  }

  base::MessageLoop message_loop_;
  TestBrowserThread io_browser_thread_;

  TestBrowserContext browser_context_;
  scoped_refptr<storage::FileSystemContext> file_system_context_;
  StreamContext* stream_context_;
  ChromeBlobStorageContext* blob_storage_context_;

  scoped_refptr<FileAPIMessageFilter> filter_;
};

TEST_F(FileAPIMessageFilterTest, CloseChannelWithInflightRequest) {
  scoped_refptr<FileAPIMessageFilter> filter(
      new FileAPIMessageFilter(
          0 /* process_id */,
          browser_context_.GetRequestContext(),
          file_system_context_.get(),
          ChromeBlobStorageContext::GetFor(&browser_context_),
          StreamContext::GetFor(&browser_context_)));
  filter->OnChannelConnected(0);

  // Complete initialization.
  message_loop_.RunUntilIdle();

  int request_id = 0;
  const GURL kUrl("filesystem:http://example.com/temporary/foo");
  FileSystemHostMsg_ReadMetadata read_metadata(request_id++, kUrl);
  EXPECT_TRUE(filter->OnMessageReceived(read_metadata));

  // Close the filter while it has inflight request.
  filter->OnChannelClosing();

  // This shouldn't cause DCHECK failure.
  message_loop_.RunUntilIdle();
}

TEST_F(FileAPIMessageFilterTest, MultipleFilters) {
  scoped_refptr<FileAPIMessageFilter> filter1(
      new FileAPIMessageFilter(
          0 /* process_id */,
          browser_context_.GetRequestContext(),
          file_system_context_.get(),
          ChromeBlobStorageContext::GetFor(&browser_context_),
          StreamContext::GetFor(&browser_context_)));
  scoped_refptr<FileAPIMessageFilter> filter2(
      new FileAPIMessageFilter(
          1 /* process_id */,
          browser_context_.GetRequestContext(),
          file_system_context_.get(),
          ChromeBlobStorageContext::GetFor(&browser_context_),
          StreamContext::GetFor(&browser_context_)));
  filter1->OnChannelConnected(0);
  filter2->OnChannelConnected(1);

  // Complete initialization.
  message_loop_.RunUntilIdle();

  int request_id = 0;
  const GURL kUrl("filesystem:http://example.com/temporary/foo");
  FileSystemHostMsg_ReadMetadata read_metadata(request_id++, kUrl);
  EXPECT_TRUE(filter1->OnMessageReceived(read_metadata));

  // Close the other filter before the request for filter1 is processed.
  filter2->OnChannelClosing();

  // This shouldn't cause DCHECK failure.
  message_loop_.RunUntilIdle();
}

TEST_F(FileAPIMessageFilterTest, BuildEmptyStream) {
  StreamRegistry* stream_registry = stream_context_->registry();

  const GURL kUrl(kFakeBlobInternalUrlSpec);
  const GURL kDifferentUrl("blob:barfoo");

  EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get());

  StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
  EXPECT_TRUE(filter_->OnMessageReceived(start_message));

  const int kBufferSize = 10;
  scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
  int bytes_read = 0;

  scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl);
  // Stream becomes available for read right after registration.
  ASSERT_FALSE(stream.get() == NULL);
  EXPECT_EQ(Stream::STREAM_EMPTY,
            stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read));
  EXPECT_EQ(0, bytes_read);
  stream = NULL;

  StreamHostMsg_FinishBuilding finish_message(kUrl);
  EXPECT_TRUE(filter_->OnMessageReceived(finish_message));

  stream = stream_registry->GetStream(kUrl);
  ASSERT_FALSE(stream.get() == NULL);
  EXPECT_EQ(Stream::STREAM_EMPTY,
            stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read));
  EXPECT_EQ(0, bytes_read);

  // Run loop to finish transfer.
  message_loop_.RunUntilIdle();

  EXPECT_EQ(Stream::STREAM_COMPLETE,
            stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read));
  EXPECT_EQ(0, bytes_read);

  // Nothing should be returned for a URL we didn't use.
  EXPECT_TRUE(stream_registry->GetStream(kDifferentUrl).get() == NULL);
}

TEST_F(FileAPIMessageFilterTest, BuildNonEmptyStream) {
  StreamRegistry* stream_registry = stream_context_->registry();

  const GURL kUrl(kFakeBlobInternalUrlSpec);

  EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get());

  StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
  EXPECT_TRUE(filter_->OnMessageReceived(start_message));

  storage::DataElement item;
  const std::string kFakeData = "foobarbaz";
  item.SetToBytes(kFakeData.data(), kFakeData.size());
  StreamHostMsg_AppendBlobDataItem append_message(kUrl, item);
  EXPECT_TRUE(filter_->OnMessageReceived(append_message));

  StreamHostMsg_FinishBuilding finish_message(kUrl);
  EXPECT_TRUE(filter_->OnMessageReceived(finish_message));

  // Run loop to finish transfer and commit finalize command.
  message_loop_.RunUntilIdle();

  scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kFakeData.size()));
  int bytes_read = 0;

  scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl);
  ASSERT_FALSE(stream.get() == NULL);

  EXPECT_EQ(Stream::STREAM_HAS_DATA,
            stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read));
  EXPECT_EQ(kFakeData.size(), static_cast<size_t>(bytes_read));
  EXPECT_EQ(kFakeData, std::string(buffer->data(), bytes_read));

  EXPECT_EQ(Stream::STREAM_COMPLETE,
            stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read));
  EXPECT_EQ(0, bytes_read);
}

TEST_F(FileAPIMessageFilterTest, BuildStreamWithSharedMemory) {
  StreamRegistry* stream_registry = stream_context_->registry();

  const GURL kUrl(kFakeBlobInternalUrlSpec);

  EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get());

  // For win, we need to set valid process to the filter.
  // OnAppendSharedMemoryToStream passes the peer process's handle to
  // SharedMemory's constructor. If it's incorrect, DuplicateHandle won't work
  // correctly.
  filter_->set_peer_process_for_testing(base::Process::Current());

  StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
  EXPECT_TRUE(filter_->OnMessageReceived(start_message));

  const std::string kFakeData = "foobarbaz";

  scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
  ASSERT_TRUE(shared_memory->CreateAndMapAnonymous(kFakeData.size()));
  memcpy(shared_memory->memory(), kFakeData.data(), kFakeData.size());
  StreamHostMsg_SyncAppendSharedMemory append_message(
      kUrl, shared_memory->handle(), kFakeData.size());
  EXPECT_TRUE(filter_->OnMessageReceived(append_message));

  StreamHostMsg_FinishBuilding finish_message(kUrl);
  EXPECT_TRUE(filter_->OnMessageReceived(finish_message));

  // Run loop to finish transfer and commit finalize command.
  message_loop_.RunUntilIdle();

  scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kFakeData.size()));
  int bytes_read = 0;

  scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl);
  ASSERT_FALSE(stream.get() == NULL);

  EXPECT_EQ(Stream::STREAM_HAS_DATA,
            stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read));
  EXPECT_EQ(kFakeData.size(), static_cast<size_t>(bytes_read));
  EXPECT_EQ(kFakeData, std::string(buffer->data(), bytes_read));

  EXPECT_EQ(Stream::STREAM_COMPLETE,
            stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read));
  EXPECT_EQ(0, bytes_read);
}

TEST_F(FileAPIMessageFilterTest, BuildStreamAndCallOnChannelClosing) {
  StreamRegistry* stream_registry = stream_context_->registry();

  const GURL kUrl(kFakeBlobInternalUrlSpec);

  StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
  EXPECT_TRUE(filter_->OnMessageReceived(start_message));

  ASSERT_FALSE(stream_registry->GetStream(kUrl).get() == NULL);

  filter_->OnChannelClosing();

  ASSERT_EQ(NULL, stream_registry->GetStream(kUrl).get());
}

TEST_F(FileAPIMessageFilterTest, CloneStream) {
  StreamRegistry* stream_registry = stream_context_->registry();

  const GURL kUrl(kFakeBlobInternalUrlSpec);
  const GURL kDestUrl(kFakeBlobInternalUrlSpec2);

  StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType);
  EXPECT_TRUE(filter_->OnMessageReceived(start_message));

  StreamHostMsg_Clone clone_message(kDestUrl, kUrl);
  EXPECT_TRUE(filter_->OnMessageReceived(clone_message));

  ASSERT_FALSE(stream_registry->GetStream(kUrl).get() == NULL);
  ASSERT_FALSE(stream_registry->GetStream(kDestUrl).get() == NULL);
}

}  // namespace content
