// 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_util.h"

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

#include "base/files/file_path.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/chromeos/drive/drive_integration_service.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/file_manager/app_id.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
#include "chrome/browser/chromeos/file_manager/filesystem_api_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/chromeos/file_manager/snapshot_manager.h"
#include "chrome/browser/chromeos/file_manager/volume_manager.h"
#include "chrome/browser/chromeos/fileapi/external_file_url_util.h"
#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/file_manager_private.h"
#include "components/drive/chromeos/file_system_interface.h"
#include "components/drive/drive.pb.h"
#include "components/drive/drive_api_util.h"
#include "components/drive/file_errors.h"
#include "content/public/browser/child_process_security_policy.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "ui/shell_dialogs/selected_file_info.h"

namespace file_manager_private = extensions::api::file_manager_private;

namespace file_manager {
namespace util {
namespace {

// The struct is used for GetSelectedFileInfo().
struct GetSelectedFileInfoParams {
  GetSelectedFileInfoLocalPathOption local_path_option;
  GetSelectedFileInfoCallback callback;
  std::vector<base::FilePath> file_paths;
  std::vector<ui::SelectedFileInfo> selected_files;
};

// The callback type for GetFileNativeLocalPathFor{Opening,Saving}. It receives
// the resolved local path when successful, and receives empty path for failure.
typedef base::Callback<void(const base::FilePath&)> LocalPathCallback;

// Converts a callback from Drive file system to LocalPathCallback.
void OnDriveGetFile(const base::FilePath& path,
                    const LocalPathCallback& callback,
                    drive::FileError error,
                    const base::FilePath& local_file_path,
                    std::unique_ptr<drive::ResourceEntry> entry) {
  if (error != drive::FILE_ERROR_OK)
    DLOG(ERROR) << "Failed to get " << path.value() << " with: " << error;
  callback.Run(local_file_path);
}

// Gets a resolved local file path of a non native |path| for file opening.
void GetFileNativeLocalPathForOpening(Profile* profile,
                                      const base::FilePath& path,
                                      const LocalPathCallback& callback) {
  if (drive::util::IsUnderDriveMountPoint(path)) {
    drive::FileSystemInterface* file_system =
        drive::util::GetFileSystemByProfile(profile);
    if (!file_system) {
      DLOG(ERROR) << "Drive file selected while disabled: " << path.value();
      callback.Run(base::FilePath());
      return;
    }
    file_system->GetFile(drive::util::ExtractDrivePath(path),
                         base::BindOnce(&OnDriveGetFile, path, callback));
    return;
  }

  VolumeManager::Get(profile)->snapshot_manager()->CreateManagedSnapshot(
      path, callback);
}

// Gets a resolved local file path of a non native |path| for file saving.
void GetFileNativeLocalPathForSaving(Profile* profile,
                                     const base::FilePath& path,
                                     const LocalPathCallback& callback) {
  if (drive::util::IsUnderDriveMountPoint(path)) {
    drive::FileSystemInterface* file_system =
        drive::util::GetFileSystemByProfile(profile);
    if (!file_system) {
      DLOG(ERROR) << "Drive file selected while disabled: " << path.value();
      callback.Run(base::FilePath());
      return;
    }
    file_system->GetFileForSaving(
        drive::util::ExtractDrivePath(path),
        base::BindOnce(&OnDriveGetFile, path, callback));
    return;
  }

  // TODO(kinaba): For now, the only writable non-local volume is Drive.
  NOTREACHED();
  callback.Run(base::FilePath());
}

// Forward declarations of helper functions for GetSelectedFileInfo().
void ContinueGetSelectedFileInfo(
    Profile* profile,
    std::unique_ptr<GetSelectedFileInfoParams> params,
    const base::FilePath& local_file_path);

void ContinueGetSelectedFileInfoWithDriveFsMetadata(
    Profile* profile,
    std::unique_ptr<GetSelectedFileInfoParams> params,
    drive::FileError error,
    drivefs::mojom::FileMetadataPtr metadata);

// Part of GetSelectedFileInfo().
void GetSelectedFileInfoInternal(
    Profile* profile,
    std::unique_ptr<GetSelectedFileInfoParams> params) {
  DCHECK(profile);

  for (size_t i = params->selected_files.size();
       i < params->file_paths.size(); ++i) {
    const base::FilePath& file_path = params->file_paths[i];

    if (file_manager::util::IsUnderNonNativeLocalPath(profile, file_path)) {
      // When the caller of the select file dialog wants local file paths, and
      // the selected path does not point to a native local path (e.g., Drive,
      // MTP, or provided file system), we should resolve the path.
      switch (params->local_path_option) {
        case NO_LOCAL_PATH_RESOLUTION: {
          // Pass empty local path.
          params->selected_files.emplace_back(file_path, base::FilePath());

          GURL external_file_url =
              chromeos::CreateExternalFileURLFromPath(profile, file_path);
          if (!external_file_url.is_empty()) {
            params->selected_files.back().url.emplace(
                std::move(external_file_url));
          }
          break;
        }
        case NEED_LOCAL_PATH_FOR_OPENING: {
          GetFileNativeLocalPathForOpening(
              profile,
              file_path,
              base::Bind(&ContinueGetSelectedFileInfo,
                         profile,
                         base::Passed(&params)));
          return;  // Remaining work is done in ContinueGetSelectedFileInfo.
        }
        case NEED_LOCAL_PATH_FOR_SAVING: {
          GetFileNativeLocalPathForSaving(
              profile,
              file_path,
              base::Bind(&ContinueGetSelectedFileInfo,
                         profile,
                         base::Passed(&params)));
          return;  // Remaining work is done in ContinueGetSelectedFileInfo.
        }
      }
    } else {
      // Hosted docs can only accessed by navigating to their URLs. Get the
      // metadata for the file from DriveFS and populate the |url| field in the
      // SelectedFileInfo.
      if (drive::util::HasHostedDocumentExtension(file_path)) {
        auto* integration_service =
            drive::util::GetIntegrationServiceByProfile(profile);
        base::FilePath drive_mount_relative_path;
        if (integration_service && integration_service->GetDriveFsInterface() &&
            integration_service->GetRelativeDrivePath(
                file_path, &drive_mount_relative_path)) {
          integration_service->GetDriveFsInterface()->GetMetadata(
              drive_mount_relative_path,
              base::BindOnce(&ContinueGetSelectedFileInfoWithDriveFsMetadata,
                             profile, std::move(params)));
          return;
        }
      }
      params->selected_files.emplace_back(file_path, file_path);
    }
  }
  params->callback.Run(params->selected_files);
}

// Part of GetSelectedFileInfo().
void ContinueGetSelectedFileInfo(
    Profile* profile,
    std::unique_ptr<GetSelectedFileInfoParams> params,
    const base::FilePath& local_path) {
  if (local_path.empty()) {
    params->callback.Run(std::vector<ui::SelectedFileInfo>());
    return;
  }
  const int index = params->selected_files.size();
  const base::FilePath& file_path = params->file_paths[index];
  params->selected_files.emplace_back(file_path, local_path);
  GetSelectedFileInfoInternal(profile, std::move(params));
}

// Part of GetSelectedFileInfo().
void ContinueGetSelectedFileInfoWithDriveFsMetadata(
    Profile* profile,
    std::unique_ptr<GetSelectedFileInfoParams> params,
    drive::FileError error,
    drivefs::mojom::FileMetadataPtr metadata) {
  const int index = params->selected_files.size();
  const auto& path = params->file_paths[index];
  params->selected_files.emplace_back(path, path);
  if (metadata &&
      metadata->type == drivefs::mojom::FileMetadata::Type::kHosted &&
      !metadata->alternate_url.empty()) {
    params->selected_files.back().url.emplace(
        std::move(metadata->alternate_url));
  }
  GetSelectedFileInfoInternal(profile, std::move(params));
}

}  // namespace

void FillIconSet(file_manager_private::IconSet* output,
                 const chromeos::file_system_provider::IconSet& input) {
  DCHECK(output);
  using chromeos::file_system_provider::IconSet;
  if (input.HasIcon(IconSet::IconSize::SIZE_16x16)) {
    output->icon16x16_url = std::make_unique<std::string>(
        input.GetIcon(IconSet::IconSize::SIZE_16x16).spec());
  }
  if (input.HasIcon(IconSet::IconSize::SIZE_32x32)) {
    output->icon32x32_url = std::make_unique<std::string>(
        input.GetIcon(IconSet::IconSize::SIZE_32x32).spec());
  }
}

void VolumeToVolumeMetadata(
    Profile* profile,
    const Volume& volume,
    file_manager_private::VolumeMetadata* volume_metadata) {
  DCHECK(volume_metadata);

  volume_metadata->volume_id = volume.volume_id();

  // TODO(kinaba): fill appropriate information once multi-profile support is
  // implemented.
  volume_metadata->profile.display_name = profile->GetProfileUserName();
  volume_metadata->profile.is_current_profile = true;

  if (!volume.source_path().empty()) {
    volume_metadata->source_path =
        std::make_unique<std::string>(volume.source_path().AsUTF8Unsafe());
  }

  switch (volume.source()) {
    case SOURCE_FILE:
      volume_metadata->source = file_manager_private::SOURCE_FILE;
      break;
    case SOURCE_DEVICE:
      volume_metadata->source = file_manager_private::SOURCE_DEVICE;
      volume_metadata->is_read_only_removable_device = volume
          .is_read_only_removable_device();
      break;
    case SOURCE_NETWORK:
      volume_metadata->source =
          extensions::api::file_manager_private::SOURCE_NETWORK;
      break;
    case SOURCE_SYSTEM:
      volume_metadata->source =
          extensions::api::file_manager_private::SOURCE_SYSTEM;
      break;
  }

  volume_metadata->configurable = volume.configurable();
  volume_metadata->watchable = volume.watchable();

  if (volume.type() == VOLUME_TYPE_PROVIDED) {
    volume_metadata->provider_id =
        std::make_unique<std::string>(volume.provider_id().ToString());
    volume_metadata->file_system_id =
        std::make_unique<std::string>(volume.file_system_id());
  }

  FillIconSet(&volume_metadata->icon_set, volume.icon_set());

  volume_metadata->volume_label =
      std::make_unique<std::string>(volume.volume_label());
  volume_metadata->disk_file_system_type =
      std::make_unique<std::string>(volume.file_system_type());

  switch (volume.type()) {
    case VOLUME_TYPE_GOOGLE_DRIVE:
      volume_metadata->volume_type =
          file_manager_private::VOLUME_TYPE_DRIVE;
      break;
    case VOLUME_TYPE_DOWNLOADS_DIRECTORY:
      volume_metadata->volume_type =
          file_manager_private::VOLUME_TYPE_DOWNLOADS;
      break;
    case VOLUME_TYPE_REMOVABLE_DISK_PARTITION:
      volume_metadata->volume_type =
          file_manager_private::VOLUME_TYPE_REMOVABLE;
      break;
    case VOLUME_TYPE_MOUNTED_ARCHIVE_FILE:
      volume_metadata->volume_type = file_manager_private::VOLUME_TYPE_ARCHIVE;
      break;
    case VOLUME_TYPE_PROVIDED:
      volume_metadata->volume_type = file_manager_private::VOLUME_TYPE_PROVIDED;
      break;
    case VOLUME_TYPE_MTP:
      volume_metadata->volume_type = file_manager_private::VOLUME_TYPE_MTP;
      break;
    case VOLUME_TYPE_MEDIA_VIEW:
      volume_metadata->volume_type =
          file_manager_private::VOLUME_TYPE_MEDIA_VIEW;
      break;
    case VOLUME_TYPE_CROSTINI:
      volume_metadata->volume_type = file_manager_private::VOLUME_TYPE_CROSTINI;
      break;
    case VOLUME_TYPE_ANDROID_FILES:
      volume_metadata->volume_type =
          file_manager_private::VOLUME_TYPE_ANDROID_FILES;
      break;
    case VOLUME_TYPE_TESTING:
      volume_metadata->volume_type =
          file_manager_private::VOLUME_TYPE_TESTING;
      break;
    case NUM_VOLUME_TYPE:
      NOTREACHED();
      break;
  }

  // Fill device_type iff the volume is removable partition.
  if (volume.type() == VOLUME_TYPE_REMOVABLE_DISK_PARTITION) {
    switch (volume.device_type()) {
      case chromeos::DEVICE_TYPE_UNKNOWN:
        volume_metadata->device_type =
            file_manager_private::DEVICE_TYPE_UNKNOWN;
        break;
      case chromeos::DEVICE_TYPE_USB:
        volume_metadata->device_type = file_manager_private::DEVICE_TYPE_USB;
        break;
      case chromeos::DEVICE_TYPE_SD:
        volume_metadata->device_type = file_manager_private::DEVICE_TYPE_SD;
        break;
      case chromeos::DEVICE_TYPE_OPTICAL_DISC:
      case chromeos::DEVICE_TYPE_DVD:
        volume_metadata->device_type =
            file_manager_private::DEVICE_TYPE_OPTICAL;
        break;
      case chromeos::DEVICE_TYPE_MOBILE:
        volume_metadata->device_type = file_manager_private::DEVICE_TYPE_MOBILE;
        break;
    }
    volume_metadata->device_path = std::make_unique<std::string>(
        volume.system_path_prefix().AsUTF8Unsafe());
    volume_metadata->is_parent_device =
        std::make_unique<bool>(volume.is_parent());
  } else {
    volume_metadata->device_type =
        file_manager_private::DEVICE_TYPE_NONE;
  }

  volume_metadata->is_read_only = volume.is_read_only();
  volume_metadata->has_media = volume.has_media();

  switch (volume.mount_condition()) {
    case chromeos::disks::MOUNT_CONDITION_NONE:
      volume_metadata->mount_condition =
          file_manager_private::MOUNT_CONDITION_NONE;
      break;
    case chromeos::disks::MOUNT_CONDITION_UNKNOWN_FILESYSTEM:
      volume_metadata->mount_condition =
          file_manager_private::MOUNT_CONDITION_UNKNOWN;
      break;
    case chromeos::disks::MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM:
      volume_metadata->mount_condition =
          file_manager_private::MOUNT_CONDITION_UNSUPPORTED;
      break;
  }

  // If the context is known, then pass it.
  switch (volume.mount_context()) {
    case MOUNT_CONTEXT_USER:
      volume_metadata->mount_context = file_manager_private::MOUNT_CONTEXT_USER;
      break;
    case MOUNT_CONTEXT_AUTO:
      volume_metadata->mount_context = file_manager_private::MOUNT_CONTEXT_AUTO;
      break;
    case MOUNT_CONTEXT_UNKNOWN:
      break;
  }
}

base::FilePath GetLocalPathFromURL(content::RenderFrameHost* render_frame_host,
                                   Profile* profile,
                                   const GURL& url) {
  DCHECK(render_frame_host);
  DCHECK(profile);

  scoped_refptr<storage::FileSystemContext> file_system_context =
      util::GetFileSystemContextForRenderFrameHost(profile, render_frame_host);

  const storage::FileSystemURL filesystem_url(
      file_system_context->CrackURL(url));
  base::FilePath path;
  if (!chromeos::FileSystemBackend::CanHandleURL(filesystem_url))
    return base::FilePath();
  return filesystem_url.path();
}

void GetSelectedFileInfo(content::RenderFrameHost* render_frame_host,
                         Profile* profile,
                         const std::vector<GURL>& file_urls,
                         GetSelectedFileInfoLocalPathOption local_path_option,
                         GetSelectedFileInfoCallback callback) {
  DCHECK(render_frame_host);
  DCHECK(profile);

  std::unique_ptr<GetSelectedFileInfoParams> params(
      new GetSelectedFileInfoParams);
  params->local_path_option = local_path_option;
  params->callback = callback;

  for (size_t i = 0; i < file_urls.size(); ++i) {
    const GURL& file_url = file_urls[i];
    const base::FilePath path = GetLocalPathFromURL(
        render_frame_host, profile, file_url);
    if (!path.empty()) {
      DVLOG(1) << "Selected: file path: " << path.value();
      params->file_paths.push_back(path);
    }
  }

  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&GetSelectedFileInfoInternal, profile,
                                base::Passed(&params)));
}

void SetupProfileFileAccessPermissions(int render_view_process_id,
                                       Profile* profile) {
  const base::FilePath paths[] = {
    drive::util::GetDriveMountPointPath(profile),
    util::GetDownloadsFolderForProfile(profile),
  };
  for (size_t i = 0; i < arraysize(paths); ++i) {
    content::ChildProcessSecurityPolicy::GetInstance(
        )->GrantCreateReadWriteFile(render_view_process_id, paths[i]);
  }
}

drive::EventLogger* GetLogger(Profile* profile) {
  drive::DriveIntegrationService* service =
      drive::DriveIntegrationServiceFactory::FindForProfile(profile);
  return service ? service->event_logger() : nullptr;
}

}  // namespace util
}  // namespace file_manager
