// 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 "webkit/browser/fileapi/file_system_operation_impl.h"

#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "net/base/escape.h"
#include "net/url_request/url_request.h"
#include "webkit/browser/fileapi/async_file_util.h"
#include "webkit/browser/fileapi/copy_or_move_operation_delegate.h"
#include "webkit/browser/fileapi/file_observers.h"
#include "webkit/browser/fileapi/file_system_backend.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_file_util.h"
#include "webkit/browser/fileapi/file_system_operation_context.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/browser/fileapi/file_writer_delegate.h"
#include "webkit/browser/fileapi/remove_operation_delegate.h"
#include "webkit/browser/fileapi/sandbox_file_system_backend.h"
#include "webkit/browser/quota/quota_manager.h"
#include "webkit/common/blob/shareable_file_reference.h"
#include "webkit/common/fileapi/file_system_types.h"
#include "webkit/common/fileapi/file_system_util.h"
#include "webkit/common/quota/quota_types.h"

using webkit_blob::ScopedFile;

namespace fileapi {

FileSystemOperation* FileSystemOperation::Create(
    const FileSystemURL& url,
    FileSystemContext* file_system_context,
    scoped_ptr<FileSystemOperationContext> operation_context) {
  return new FileSystemOperationImpl(url, file_system_context,
                                     operation_context.Pass());
}

FileSystemOperationImpl::~FileSystemOperationImpl() {
}

void FileSystemOperationImpl::CreateFile(const FileSystemURL& url,
                                         bool exclusive,
                                         const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCreateFile));
  GetUsageAndQuotaThenRunTask(
      url,
      base::Bind(&FileSystemOperationImpl::DoCreateFile,
                 weak_factory_.GetWeakPtr(), url, callback, exclusive),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperationImpl::CreateDirectory(const FileSystemURL& url,
                                              bool exclusive,
                                              bool recursive,
                                              const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCreateDirectory));
  GetUsageAndQuotaThenRunTask(
      url,
      base::Bind(&FileSystemOperationImpl::DoCreateDirectory,
                 weak_factory_.GetWeakPtr(), url, callback,
                 exclusive, recursive),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperationImpl::Copy(
    const FileSystemURL& src_url,
    const FileSystemURL& dest_url,
    CopyOrMoveOption option,
    const CopyProgressCallback& progress_callback,
    const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCopy));
  DCHECK(!recursive_operation_delegate_);

  // TODO(hidehiko): Support |progress_callback|. (crbug.com/278038).
  recursive_operation_delegate_.reset(
      new CopyOrMoveOperationDelegate(
          file_system_context(),
          src_url, dest_url,
          CopyOrMoveOperationDelegate::OPERATION_COPY,
          option,
          progress_callback,
          base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                     weak_factory_.GetWeakPtr(), callback)));
  recursive_operation_delegate_->RunRecursively();
}

void FileSystemOperationImpl::Move(const FileSystemURL& src_url,
                                   const FileSystemURL& dest_url,
                                   CopyOrMoveOption option,
                                   const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationMove));
  DCHECK(!recursive_operation_delegate_);
  recursive_operation_delegate_.reset(
      new CopyOrMoveOperationDelegate(
          file_system_context(),
          src_url, dest_url,
          CopyOrMoveOperationDelegate::OPERATION_MOVE,
          option,
          FileSystemOperation::CopyProgressCallback(),
          base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                     weak_factory_.GetWeakPtr(), callback)));
  recursive_operation_delegate_->RunRecursively();
}

void FileSystemOperationImpl::DirectoryExists(const FileSystemURL& url,
                                              const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationDirectoryExists));
  async_file_util_->GetFileInfo(
      operation_context_.Pass(), url,
      base::Bind(&FileSystemOperationImpl::DidDirectoryExists,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::FileExists(const FileSystemURL& url,
                                         const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationFileExists));
  async_file_util_->GetFileInfo(
      operation_context_.Pass(), url,
      base::Bind(&FileSystemOperationImpl::DidFileExists,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::GetMetadata(
    const FileSystemURL& url, const GetMetadataCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationGetMetadata));
  async_file_util_->GetFileInfo(operation_context_.Pass(), url, callback);
}

void FileSystemOperationImpl::ReadDirectory(
    const FileSystemURL& url, const ReadDirectoryCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationReadDirectory));
  async_file_util_->ReadDirectory(
      operation_context_.Pass(), url, callback);
}

void FileSystemOperationImpl::Remove(const FileSystemURL& url,
                                     bool recursive,
                                     const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationRemove));
  DCHECK(!recursive_operation_delegate_);

  if (recursive) {
    // For recursive removal, try to delegate the operation to AsyncFileUtil
    // first. If not supported, it is delegated to RemoveOperationDelegate
    // in DidDeleteRecursively.
    async_file_util_->DeleteRecursively(
        operation_context_.Pass(), url,
        base::Bind(&FileSystemOperationImpl::DidDeleteRecursively,
                   weak_factory_.GetWeakPtr(), url, callback));
    return;
  }

  recursive_operation_delegate_.reset(
      new RemoveOperationDelegate(
          file_system_context(), url,
          base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                     weak_factory_.GetWeakPtr(), callback)));
  recursive_operation_delegate_->Run();
}

void FileSystemOperationImpl::Write(
    const FileSystemURL& url,
    scoped_ptr<FileWriterDelegate> writer_delegate,
    scoped_ptr<net::URLRequest> blob_request,
    const WriteCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationWrite));
  file_writer_delegate_ = writer_delegate.Pass();
  file_writer_delegate_->Start(
      blob_request.Pass(),
      base::Bind(&FileSystemOperationImpl::DidWrite,
                 weak_factory_.GetWeakPtr(), url, callback));
}

void FileSystemOperationImpl::Truncate(const FileSystemURL& url, int64 length,
                                       const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationTruncate));
  GetUsageAndQuotaThenRunTask(
      url,
      base::Bind(&FileSystemOperationImpl::DoTruncate,
                 weak_factory_.GetWeakPtr(), url, callback, length),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperationImpl::TouchFile(const FileSystemURL& url,
                                        const base::Time& last_access_time,
                                        const base::Time& last_modified_time,
                                        const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationTouchFile));
  async_file_util_->Touch(
      operation_context_.Pass(), url,
      last_access_time, last_modified_time,
      base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::OpenFile(const FileSystemURL& url,
                                       int file_flags,
                                       const OpenFileCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationOpenFile));

  if (file_flags &
      (base::PLATFORM_FILE_TEMPORARY | base::PLATFORM_FILE_HIDDEN)) {
    callback.Run(base::PLATFORM_FILE_ERROR_FAILED,
                 base::kInvalidPlatformFileValue,
                 base::Closure());
    return;
  }
  GetUsageAndQuotaThenRunTask(
      url,
      base::Bind(&FileSystemOperationImpl::DoOpenFile,
                 weak_factory_.GetWeakPtr(),
                 url, callback, file_flags),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED,
                 base::kInvalidPlatformFileValue,
                 base::Closure()));
}

// We can only get here on a write or truncate that's not yet completed.
// We don't support cancelling any other operation at this time.
void FileSystemOperationImpl::Cancel(const StatusCallback& cancel_callback) {
  DCHECK(cancel_callback_.is_null());
  cancel_callback_ = cancel_callback;

  if (file_writer_delegate_.get()) {
    DCHECK_EQ(kOperationWrite, pending_operation_);
    // This will call DidWrite() with ABORT status code.
    file_writer_delegate_->Cancel();
  } else if (recursive_operation_delegate_) {
    // This will call DidFinishOperation() with ABORT status code.
    recursive_operation_delegate_->Cancel();
  } else {
    // For truncate we have no way to cancel the inflight operation (for now).
    // Let it just run and dispatch cancel callback later.
    DCHECK_EQ(kOperationTruncate, pending_operation_);
  }
}

void FileSystemOperationImpl::CreateSnapshotFile(
    const FileSystemURL& url,
    const SnapshotFileCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCreateSnapshotFile));
  async_file_util_->CreateSnapshotFile(
      operation_context_.Pass(), url, callback);
}

void FileSystemOperationImpl::CopyInForeignFile(
    const base::FilePath& src_local_disk_file_path,
    const FileSystemURL& dest_url,
    const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCopyInForeignFile));
  GetUsageAndQuotaThenRunTask(
      dest_url,
      base::Bind(&FileSystemOperationImpl::DoCopyInForeignFile,
                 weak_factory_.GetWeakPtr(), src_local_disk_file_path, dest_url,
                 callback),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperationImpl::RemoveFile(
    const FileSystemURL& url,
    const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationRemove));
  async_file_util_->DeleteFile(
      operation_context_.Pass(), url,
      base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::RemoveDirectory(
    const FileSystemURL& url,
    const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationRemove));
  async_file_util_->DeleteDirectory(
      operation_context_.Pass(), url,
      base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::CopyFileLocal(
    const FileSystemURL& src_url,
    const FileSystemURL& dest_url,
    CopyOrMoveOption option,
    const CopyFileProgressCallback& progress_callback,
    const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationCopy));
  DCHECK(src_url.IsInSameFileSystem(dest_url));

  GetUsageAndQuotaThenRunTask(
      dest_url,
      base::Bind(&FileSystemOperationImpl::DoCopyFileLocal,
                 weak_factory_.GetWeakPtr(), src_url, dest_url, option,
                 progress_callback, callback),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

void FileSystemOperationImpl::MoveFileLocal(
    const FileSystemURL& src_url,
    const FileSystemURL& dest_url,
    CopyOrMoveOption option,
    const StatusCallback& callback) {
  DCHECK(SetPendingOperationType(kOperationMove));
  DCHECK(src_url.IsInSameFileSystem(dest_url));
  GetUsageAndQuotaThenRunTask(
      dest_url,
      base::Bind(&FileSystemOperationImpl::DoMoveFileLocal,
                 weak_factory_.GetWeakPtr(),
                 src_url, dest_url, option, callback),
      base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED));
}

base::PlatformFileError FileSystemOperationImpl::SyncGetPlatformPath(
    const FileSystemURL& url,
    base::FilePath* platform_path) {
  DCHECK(SetPendingOperationType(kOperationGetLocalPath));
  if (!file_system_context()->IsSandboxFileSystem(url.type()))
    return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
  FileSystemFileUtil* file_util =
      file_system_context()->sandbox_delegate()->sync_file_util();
  file_util->GetLocalFilePath(operation_context_.get(), url, platform_path);
  return base::PLATFORM_FILE_OK;
}

FileSystemOperationImpl::FileSystemOperationImpl(
    const FileSystemURL& url,
    FileSystemContext* file_system_context,
    scoped_ptr<FileSystemOperationContext> operation_context)
    : file_system_context_(file_system_context),
      operation_context_(operation_context.Pass()),
      async_file_util_(NULL),
      pending_operation_(kOperationNone),
      weak_factory_(this) {
  DCHECK(operation_context_.get());
  operation_context_->DetachUserDataThread();
  async_file_util_ = file_system_context_->GetAsyncFileUtil(url.type());
  DCHECK(async_file_util_);
}

void FileSystemOperationImpl::GetUsageAndQuotaThenRunTask(
    const FileSystemURL& url,
    const base::Closure& task,
    const base::Closure& error_callback) {
  quota::QuotaManagerProxy* quota_manager_proxy =
      file_system_context()->quota_manager_proxy();
  if (!quota_manager_proxy ||
      !file_system_context()->GetQuotaUtil(url.type())) {
    // If we don't have the quota manager or the requested filesystem type
    // does not support quota, we should be able to let it go.
    operation_context_->set_allowed_bytes_growth(kint64max);
    task.Run();
    return;
  }

  DCHECK(quota_manager_proxy);
  DCHECK(quota_manager_proxy->quota_manager());
  quota_manager_proxy->quota_manager()->GetUsageAndQuota(
      url.origin(),
      FileSystemTypeToQuotaStorageType(url.type()),
      base::Bind(&FileSystemOperationImpl::DidGetUsageAndQuotaAndRunTask,
                 weak_factory_.GetWeakPtr(), task, error_callback));
}

void FileSystemOperationImpl::DidGetUsageAndQuotaAndRunTask(
    const base::Closure& task,
    const base::Closure& error_callback,
    quota::QuotaStatusCode status,
    int64 usage, int64 quota) {
  if (status != quota::kQuotaStatusOk) {
    LOG(WARNING) << "Got unexpected quota error : " << status;
    error_callback.Run();
    return;
  }

  operation_context_->set_allowed_bytes_growth(quota - usage);
  task.Run();
}

void FileSystemOperationImpl::DoCreateFile(
    const FileSystemURL& url,
    const StatusCallback& callback,
    bool exclusive) {
  async_file_util_->EnsureFileExists(
      operation_context_.Pass(), url,
      base::Bind(
          exclusive ?
              &FileSystemOperationImpl::DidEnsureFileExistsExclusive :
              &FileSystemOperationImpl::DidEnsureFileExistsNonExclusive,
          weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::DoCreateDirectory(
    const FileSystemURL& url,
    const StatusCallback& callback,
    bool exclusive, bool recursive) {
  async_file_util_->CreateDirectory(
      operation_context_.Pass(),
      url, exclusive, recursive,
      base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::DoCopyFileLocal(
    const FileSystemURL& src_url,
    const FileSystemURL& dest_url,
    CopyOrMoveOption option,
    const CopyFileProgressCallback& progress_callback,
    const StatusCallback& callback) {
  async_file_util_->CopyFileLocal(
      operation_context_.Pass(), src_url, dest_url, option, progress_callback,
      base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::DoMoveFileLocal(
    const FileSystemURL& src_url,
    const FileSystemURL& dest_url,
    CopyOrMoveOption option,
    const StatusCallback& callback) {
  async_file_util_->MoveFileLocal(
      operation_context_.Pass(), src_url, dest_url, option,
      base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::DoCopyInForeignFile(
    const base::FilePath& src_local_disk_file_path,
    const FileSystemURL& dest_url,
    const StatusCallback& callback) {
  async_file_util_->CopyInForeignFile(
      operation_context_.Pass(),
      src_local_disk_file_path, dest_url,
      base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::DoTruncate(const FileSystemURL& url,
                                         const StatusCallback& callback,
                                         int64 length) {
  async_file_util_->Truncate(
      operation_context_.Pass(), url, length,
      base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::DoOpenFile(const FileSystemURL& url,
                                         const OpenFileCallback& callback,
                                         int file_flags) {
  async_file_util_->CreateOrOpen(
      operation_context_.Pass(), url, file_flags,
      base::Bind(&FileSystemOperationImpl::DidOpenFile,
                 weak_factory_.GetWeakPtr(), callback));
}

void FileSystemOperationImpl::DidEnsureFileExistsExclusive(
    const StatusCallback& callback,
    base::PlatformFileError rv, bool created) {
  if (rv == base::PLATFORM_FILE_OK && !created) {
    callback.Run(base::PLATFORM_FILE_ERROR_EXISTS);
  } else {
    DidFinishOperation(callback, rv);
  }
}

void FileSystemOperationImpl::DidEnsureFileExistsNonExclusive(
    const StatusCallback& callback,
    base::PlatformFileError rv, bool /* created */) {
  DidFinishOperation(callback, rv);
}

void FileSystemOperationImpl::DidFinishOperation(
    const StatusCallback& callback,
    base::PlatformFileError rv) {
  if (!cancel_callback_.is_null()) {
    StatusCallback cancel_callback = cancel_callback_;
    callback.Run(rv);

    // Return OK only if we succeeded to stop the operation.
    cancel_callback.Run(rv == base::PLATFORM_FILE_ERROR_ABORT ?
                        base::PLATFORM_FILE_OK :
                        base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
  } else {
    callback.Run(rv);
  }
}

void FileSystemOperationImpl::DidDirectoryExists(
    const StatusCallback& callback,
    base::PlatformFileError rv,
    const base::PlatformFileInfo& file_info) {
  if (rv == base::PLATFORM_FILE_OK && !file_info.is_directory)
    rv = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
  callback.Run(rv);
}

void FileSystemOperationImpl::DidFileExists(
    const StatusCallback& callback,
    base::PlatformFileError rv,
    const base::PlatformFileInfo& file_info) {
  if (rv == base::PLATFORM_FILE_OK && file_info.is_directory)
    rv = base::PLATFORM_FILE_ERROR_NOT_A_FILE;
  callback.Run(rv);
}

void FileSystemOperationImpl::DidDeleteRecursively(
    const FileSystemURL& url,
    const StatusCallback& callback,
    base::PlatformFileError rv) {
  if (rv == base::PLATFORM_FILE_ERROR_INVALID_OPERATION) {
    // Recursive removal is not supported on this platform.
    DCHECK(!recursive_operation_delegate_);
    recursive_operation_delegate_.reset(
        new RemoveOperationDelegate(
            file_system_context(), url,
            base::Bind(&FileSystemOperationImpl::DidFinishOperation,
                       weak_factory_.GetWeakPtr(), callback)));
    recursive_operation_delegate_->RunRecursively();
    return;
  }

  callback.Run(rv);
}

void FileSystemOperationImpl::DidWrite(
    const FileSystemURL& url,
    const WriteCallback& write_callback,
    base::PlatformFileError rv,
    int64 bytes,
    FileWriterDelegate::WriteProgressStatus write_status) {
  const bool complete = (
      write_status != FileWriterDelegate::SUCCESS_IO_PENDING);
  if (complete && write_status != FileWriterDelegate::ERROR_WRITE_NOT_STARTED) {
    DCHECK(operation_context_);
    operation_context_->change_observers()->Notify(
        &FileChangeObserver::OnModifyFile, MakeTuple(url));
  }

  StatusCallback cancel_callback = cancel_callback_;
  write_callback.Run(rv, bytes, complete);
  if (!cancel_callback.is_null())
    cancel_callback.Run(base::PLATFORM_FILE_OK);
}

void FileSystemOperationImpl::DidOpenFile(
    const OpenFileCallback& callback,
    base::PlatformFileError rv,
    base::PassPlatformFile file,
    const base::Closure& on_close_callback) {
  callback.Run(rv, file.ReleaseValue(), on_close_callback);
}

bool FileSystemOperationImpl::SetPendingOperationType(OperationType type) {
  if (pending_operation_ != kOperationNone)
    return false;
  pending_operation_ = type;
  return true;
}

}  // namespace fileapi
