// 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 "components/drive/file_system/open_file_operation.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback_helpers.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/task_runner_util.h"
#include "base/thread_task_runner_handle.h"
#include "components/drive/drive.pb.h"
#include "components/drive/file_cache.h"
#include "components/drive/file_errors.h"
#include "components/drive/file_system/create_file_operation.h"
#include "components/drive/file_system/download_operation.h"
#include "components/drive/file_system/operation_delegate.h"
#include "components/drive/job_scheduler.h"

namespace drive {
namespace file_system {

OpenFileOperation::OpenFileOperation(
    base::SequencedTaskRunner* blocking_task_runner,
    OperationDelegate* delegate,
    JobScheduler* scheduler,
    internal::ResourceMetadata* metadata,
    internal::FileCache* cache,
    const base::FilePath& temporary_file_directory)
    : blocking_task_runner_(blocking_task_runner),
      delegate_(delegate),
      cache_(cache),
      create_file_operation_(new CreateFileOperation(
          blocking_task_runner, delegate, metadata)),
      download_operation_(new DownloadOperation(
          blocking_task_runner, delegate, scheduler,
          metadata, cache, temporary_file_directory)),
      weak_ptr_factory_(this) {
}

OpenFileOperation::~OpenFileOperation() {
}

void OpenFileOperation::OpenFile(const base::FilePath& file_path,
                                 OpenMode open_mode,
                                 const std::string& mime_type,
                                 const OpenFileCallback& callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!callback.is_null());

  switch (open_mode) {
    case OPEN_FILE:
      // It is not necessary to create a new file even if not exists.
      // So call OpenFileAfterCreateFile directly with FILE_ERROR_OK
      // to skip file creation.
      OpenFileAfterCreateFile(file_path, callback, FILE_ERROR_OK);
      break;
    case CREATE_FILE:
      create_file_operation_->CreateFile(
          file_path,
          true,  // exclusive: fail if already exists
          mime_type,
          base::Bind(&OpenFileOperation::OpenFileAfterCreateFile,
                     weak_ptr_factory_.GetWeakPtr(), file_path, callback));
      break;
    case OPEN_OR_CREATE_FILE:
      create_file_operation_->CreateFile(
          file_path,
          false,  // not-exclusive
          mime_type,
          base::Bind(&OpenFileOperation::OpenFileAfterCreateFile,
                     weak_ptr_factory_.GetWeakPtr(), file_path, callback));
      break;
  }
}

void OpenFileOperation::OpenFileAfterCreateFile(
    const base::FilePath& file_path,
    const OpenFileCallback& callback,
    FileError error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!callback.is_null());

  if (error != FILE_ERROR_OK) {
    callback.Run(error, base::FilePath(), base::Closure());
    return;
  }

  download_operation_->EnsureFileDownloadedByPath(
      file_path,
      ClientContext(USER_INITIATED),
      GetFileContentInitializedCallback(),
      google_apis::GetContentCallback(),
      base::Bind(
          &OpenFileOperation::OpenFileAfterFileDownloaded,
          weak_ptr_factory_.GetWeakPtr(), callback));
}

void OpenFileOperation::OpenFileAfterFileDownloaded(
    const OpenFileCallback& callback,
    FileError error,
    const base::FilePath& local_file_path,
    scoped_ptr<ResourceEntry> entry) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!callback.is_null());

  if (error == FILE_ERROR_OK) {
    DCHECK(entry);
    DCHECK(entry->has_file_specific_info());
    if (entry->file_specific_info().is_hosted_document())
      // No support for opening a hosted document.
      error = FILE_ERROR_INVALID_OPERATION;
  }

  if (error != FILE_ERROR_OK) {
    callback.Run(error, base::FilePath(), base::Closure());
    return;
  }

  scoped_ptr<base::ScopedClosureRunner>* file_closer =
      new scoped_ptr<base::ScopedClosureRunner>;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner_.get(),
      FROM_HERE,
      base::Bind(&internal::FileCache::OpenForWrite,
                 base::Unretained(cache_),
                 entry->local_id(),
                 file_closer),
      base::Bind(&OpenFileOperation::OpenFileAfterOpenForWrite,
                 weak_ptr_factory_.GetWeakPtr(),
                 local_file_path,
                 entry->local_id(),
                 callback,
                 base::Owned(file_closer)));
}

void OpenFileOperation::OpenFileAfterOpenForWrite(
    const base::FilePath& local_file_path,
    const std::string& local_id,
    const OpenFileCallback& callback,
    scoped_ptr<base::ScopedClosureRunner>* file_closer,
    FileError error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!callback.is_null());

  if (error != FILE_ERROR_OK) {
    callback.Run(error, base::FilePath(), base::Closure());
    return;
  }

  ++open_files_[local_id];
  callback.Run(error, local_file_path,
               base::Bind(&OpenFileOperation::CloseFile,
                          weak_ptr_factory_.GetWeakPtr(),
                          local_id,
                          base::Passed(file_closer)));
}

void OpenFileOperation::CloseFile(
    const std::string& local_id,
    scoped_ptr<base::ScopedClosureRunner> file_closer) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_GT(open_files_[local_id], 0);

  if (--open_files_[local_id] == 0) {
    // All clients closes this file, so notify to upload the file.
    open_files_.erase(local_id);
    delegate_->OnEntryUpdatedByOperation(ClientContext(USER_INITIATED),
                                         local_id);

    // Clients may have enlarged the file. By FreeDiskpSpaceIfNeededFor(0),
    // we try to ensure (0 + the-minimum-safe-margin = 512MB as of now) space.
    blocking_task_runner_->PostTask(
        FROM_HERE,
        base::Bind(base::IgnoreResult(
            base::Bind(&internal::FileCache::FreeDiskSpaceIfNeededFor,
                       base::Unretained(cache_),
                       0))));
  }
}

}  // namespace file_system
}  // namespace drive
