// 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 "chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h"

#include <stddef.h>

#include <set>
#include <string>
#include <vector>

#include "base/memory/ptr_util.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
#include "chrome/browser/extensions/api/file_handlers/directory_util.h"
#include "chrome/browser/extensions/api/file_handlers/mime_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/file_manager_private.h"
#include "chrome/common/extensions/api/file_manager_private_internal.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/entry_info.h"
#include "net/base/filename_util.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_url.h"

using content::BrowserThread;
using storage::FileSystemURL;

namespace extensions {
namespace {

// Error messages.
const char kInvalidTask[] = "Invalid task: ";
const char kInvalidFileUrl[] = "Invalid file URL";

// Make a set of unique filename suffixes out of the list of file URLs.
std::set<std::string> GetUniqueSuffixes(
    const std::vector<std::string>& url_list,
    const storage::FileSystemContext* context) {
  std::set<std::string> suffixes;
  for (size_t i = 0; i < url_list.size(); ++i) {
    const FileSystemURL url = context->CrackURL(GURL(url_list[i]));
    if (!url.is_valid() || url.path().empty())
      return std::set<std::string>();
    // We'll skip empty suffixes.
    if (!url.path().Extension().empty())
      suffixes.insert(url.path().Extension());
  }
  return suffixes;
}

// Make a set of unique MIME types out of the list of MIME types.
std::set<std::string> GetUniqueMimeTypes(
    const std::vector<std::string>& mime_type_list) {
  std::set<std::string> mime_types;
  for (size_t i = 0; i < mime_type_list.size(); ++i) {
    const std::string mime_type = mime_type_list[i];
    // We'll skip empty MIME types and existing MIME types.
    if (!mime_type.empty())
      mime_types.insert(mime_type);
  }
  return mime_types;
}

}  // namespace

bool FileManagerPrivateInternalExecuteTaskFunction::RunAsync() {
  using extensions::api::file_manager_private_internal::ExecuteTask::Params;
  using extensions::api::file_manager_private_internal::ExecuteTask::Results::
      Create;
  const std::unique_ptr<Params> params(Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params);

  file_manager::file_tasks::TaskDescriptor task;
  if (!file_manager::file_tasks::ParseTaskID(params->task_id, &task)) {
    SetError(kInvalidTask + params->task_id);
    results_ =
        Create(extensions::api::file_manager_private::TASK_RESULT_FAILED);
    return false;
  }

  if (params->urls.empty()) {
    results_ = Create(extensions::api::file_manager_private::TASK_RESULT_EMPTY);
    SendResponse(true);
    return true;
  }

  const scoped_refptr<storage::FileSystemContext> file_system_context =
      file_manager::util::GetFileSystemContextForRenderFrameHost(
          GetProfile(), render_frame_host());

  std::vector<FileSystemURL> urls;
  for (size_t i = 0; i < params->urls.size(); i++) {
    const FileSystemURL url =
        file_system_context->CrackURL(GURL(params->urls[i]));
    if (!chromeos::FileSystemBackend::CanHandleURL(url)) {
      SetError(kInvalidFileUrl);
      results_ =
          Create(extensions::api::file_manager_private::TASK_RESULT_FAILED);
      return false;
    }
    urls.push_back(url);
  }

  const bool result = file_manager::file_tasks::ExecuteFileTask(
      GetProfile(), source_url(), task, urls,
      base::Bind(&FileManagerPrivateInternalExecuteTaskFunction::OnTaskExecuted,
                 this));
  if (!result) {
    results_ =
        Create(extensions::api::file_manager_private::TASK_RESULT_FAILED);
  }
  return result;
}

void FileManagerPrivateInternalExecuteTaskFunction::OnTaskExecuted(
    extensions::api::file_manager_private::TaskResult result) {
  results_ = extensions::api::file_manager_private_internal::ExecuteTask::
      Results::Create(result);
  SendResponse(result !=
               extensions::api::file_manager_private::TASK_RESULT_FAILED);
}

FileManagerPrivateInternalGetFileTasksFunction::
    FileManagerPrivateInternalGetFileTasksFunction() {}

FileManagerPrivateInternalGetFileTasksFunction::
    ~FileManagerPrivateInternalGetFileTasksFunction() {}

bool FileManagerPrivateInternalGetFileTasksFunction::RunAsync() {
  using extensions::api::file_manager_private_internal::GetFileTasks::Params;
  const std::unique_ptr<Params> params(Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params);

  if (params->urls.empty())
    return false;

  const scoped_refptr<storage::FileSystemContext> file_system_context =
      file_manager::util::GetFileSystemContextForRenderFrameHost(
          GetProfile(), render_frame_host());

  // Collect all the URLs, convert them to GURLs, and crack all the urls into
  // file paths.
  for (size_t i = 0; i < params->urls.size(); ++i) {
    const GURL url(params->urls[i]);
    storage::FileSystemURL file_system_url(file_system_context->CrackURL(url));
    if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url))
      continue;
    urls_.push_back(url);
    local_paths_.push_back(file_system_url.path());
  }

  mime_type_collector_.reset(
      new app_file_handler_util::MimeTypeCollector(GetProfile()));
  mime_type_collector_->CollectForLocalPaths(
      local_paths_,
      base::Bind(
          &FileManagerPrivateInternalGetFileTasksFunction::OnMimeTypesCollected,
          this));

  return true;
}

void FileManagerPrivateInternalGetFileTasksFunction::OnMimeTypesCollected(
    std::unique_ptr<std::vector<std::string>> mime_types) {
  is_directory_collector_.reset(
      new app_file_handler_util::IsDirectoryCollector(GetProfile()));
  is_directory_collector_->CollectForEntriesPaths(
      local_paths_, base::Bind(&FileManagerPrivateInternalGetFileTasksFunction::
                                   OnAreDirectoriesAndMimeTypesCollected,
                               this, base::Passed(std::move(mime_types))));
}

void FileManagerPrivateInternalGetFileTasksFunction::
    OnAreDirectoriesAndMimeTypesCollected(
        std::unique_ptr<std::vector<std::string>> mime_types,
        std::unique_ptr<std::set<base::FilePath>> directory_paths) {
  std::vector<EntryInfo> entries;
  for (size_t i = 0; i < local_paths_.size(); ++i) {
    entries.push_back(EntryInfo(
        local_paths_[i], (*mime_types)[i],
        directory_paths->find(local_paths_[i]) != directory_paths->end()));
  }

  file_manager::file_tasks::FindAllTypesOfTasks(
      GetProfile(), drive::util::GetDriveAppRegistryByProfile(GetProfile()),
      entries, urls_,
      base::Bind(
          &FileManagerPrivateInternalGetFileTasksFunction::OnFileTasksListed,
          this));
}

void FileManagerPrivateInternalGetFileTasksFunction::OnFileTasksListed(
    std::unique_ptr<std::vector<file_manager::file_tasks::FullTaskDescriptor>>
        tasks) {
  // Convert the tasks into JSON compatible objects.
  using api::file_manager_private::FileTask;
  std::vector<FileTask> results;
  for (const file_manager::file_tasks::FullTaskDescriptor& task : *tasks) {
    FileTask converted;
    converted.task_id =
        file_manager::file_tasks::TaskDescriptorToId(task.task_descriptor());
    if (!task.icon_url().is_empty())
      converted.icon_url = task.icon_url().spec();
    converted.title = task.task_title();
    converted.is_default = task.is_default();
    converted.is_generic_file_handler = task.is_generic_file_handler();
    results.push_back(std::move(converted));
  }

  results_ = extensions::api::file_manager_private_internal::GetFileTasks::
      Results::Create(results);
  SendResponse(true);
}

bool FileManagerPrivateInternalSetDefaultTaskFunction::RunSync() {
  using extensions::api::file_manager_private_internal::SetDefaultTask::Params;
  const std::unique_ptr<Params> params(Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params);

  const scoped_refptr<storage::FileSystemContext> file_system_context =
      file_manager::util::GetFileSystemContextForRenderFrameHost(
          GetProfile(), render_frame_host());

  const std::set<std::string> suffixes =
      GetUniqueSuffixes(params->urls, file_system_context.get());
  const std::set<std::string> mime_types =
      GetUniqueMimeTypes(params->mime_types);

  // If there weren't any mime_types, and all the suffixes were blank,
  // then we "succeed", but don't actually associate with anything.
  // Otherwise, any time we set the default on a file with no extension
  // on the local drive, we'd fail.
  // TODO(gspencer): Fix file manager so that it never tries to set default in
  // cases where extensionless local files are part of the selection.
  if (suffixes.empty() && mime_types.empty()) {
    SetResult(base::MakeUnique<base::FundamentalValue>(true));
    return true;
  }

  file_manager::file_tasks::UpdateDefaultTask(
      GetProfile()->GetPrefs(), params->task_id, suffixes, mime_types);
  return true;
}

}  // namespace extensions
