// Copyright (c) 2012 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/browser_file_system_helper.h"

#include <stddef.h>
#include <string>
#include <utility>
#include <vector>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "storage/browser/fileapi/external_mount_points.h"
#include "storage/browser/fileapi/file_permission_policy.h"
#include "storage/browser/fileapi/file_system_backend.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_operation_runner.h"
#include "storage/browser/fileapi/file_system_options.h"
#include "storage/browser/quota/quota_manager.h"
#include "url/url_constants.h"

namespace content {

namespace {

using storage::FileSystemOptions;

FileSystemOptions CreateBrowserFileSystemOptions(bool is_incognito) {
  FileSystemOptions::ProfileMode profile_mode =
      is_incognito ? FileSystemOptions::PROFILE_MODE_INCOGNITO
                   : FileSystemOptions::PROFILE_MODE_NORMAL;
  std::vector<std::string> additional_allowed_schemes;
  GetContentClient()->browser()->GetAdditionalAllowedSchemesForFileSystem(
      &additional_allowed_schemes);
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kAllowFileAccessFromFiles)) {
    additional_allowed_schemes.push_back(url::kFileScheme);
  }
  return FileSystemOptions(profile_mode, additional_allowed_schemes, NULL);
}

}  // namespace

scoped_refptr<storage::FileSystemContext> CreateFileSystemContext(
    BrowserContext* browser_context,
    const base::FilePath& profile_path,
    bool is_incognito,
    storage::QuotaManagerProxy* quota_manager_proxy) {
  base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
  scoped_refptr<base::SequencedTaskRunner> file_task_runner =
      pool->GetSequencedTaskRunnerWithShutdownBehavior(
          pool->GetNamedSequenceToken("FileAPI"),
          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);

  // Setting up additional filesystem backends.
  ScopedVector<storage::FileSystemBackend> additional_backends;
  GetContentClient()->browser()->GetAdditionalFileSystemBackends(
      browser_context,
      profile_path,
      &additional_backends);

  // Set up the auto mount handlers for url requests.
  std::vector<storage::URLRequestAutoMountHandler>
      url_request_auto_mount_handlers;
  GetContentClient()->browser()->GetURLRequestAutoMountHandlers(
      &url_request_auto_mount_handlers);

  scoped_refptr<storage::FileSystemContext> file_system_context =
      new storage::FileSystemContext(
          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
          file_task_runner.get(),
          BrowserContext::GetMountPoints(browser_context),
          browser_context->GetSpecialStoragePolicy(), quota_manager_proxy,
          std::move(additional_backends), url_request_auto_mount_handlers,
          profile_path, CreateBrowserFileSystemOptions(is_incognito));

  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]));
  }

  return file_system_context;
}

bool FileSystemURLIsValid(storage::FileSystemContext* context,
                          const storage::FileSystemURL& url) {
  if (!url.is_valid())
    return false;

  return context->GetFileSystemBackend(url.type()) != NULL;
}

void SyncGetPlatformPath(storage::FileSystemContext* context,
                         int process_id,
                         const GURL& path,
                         base::FilePath* platform_path) {
  DCHECK(context->default_file_task_runner()->
         RunsTasksOnCurrentThread());
  DCHECK(platform_path);
  *platform_path = base::FilePath();
  storage::FileSystemURL url(context->CrackURL(path));
  if (!FileSystemURLIsValid(context, url))
    return;

  // Make sure if this file is ok to be read (in the current architecture
  // which means roughly same as the renderer is allowed to get the platform
  // path to the file).
  ChildProcessSecurityPolicyImpl* policy =
      ChildProcessSecurityPolicyImpl::GetInstance();
  if (!policy->CanReadFileSystemFile(process_id, url))
    return;

  context->operation_runner()->SyncGetPlatformPath(url, platform_path);

  // The path is to be attached to URLLoader so we grant read permission
  // for the file. (We need to check first because a parent directory may
  // already have the permissions and we don't need to grant it to the file.)
  if (!policy->CanReadFile(process_id, *platform_path))
    policy->GrantReadFile(process_id, *platform_path);
}

}  // namespace content
