// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/data_transfer_util.h"

#include <string>
#include <utility>
#include <vector>

#include "base/check.h"
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "base/uuid.h"
#include "build/chromeos_buildflags.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/file_system_access/file_system_access_manager_impl.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/mime_util.h"
#include "services/network/public/mojom/referrer_policy.mojom-shared.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/file_system/external_mount_points.h"
#include "storage/browser/file_system/file_system_context.h"
#include "third_party/blink/public/mojom/blob/serialized_blob.mojom.h"
#include "third_party/blink/public/mojom/drag/drag.mojom.h"
#include "third_party/blink/public/mojom/file_system_access/file_system_access_data_transfer_token.mojom.h"
#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/clipboard/file_info.h"
#include "url/gurl.h"

namespace content {

namespace {

// On Chrome OS paths that exist on an external mount point need to be treated
// differently to make sure the File System Access code accesses these paths via
// the correct file system backend. This method checks if this is the case, and
// updates `entry_path` to the path that should be used by the File System
// Access implementation.
content::FileSystemAccessEntryFactory::PathType MaybeRemapPath(
    base::FilePath* entry_path) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  base::FilePath virtual_path;
  auto* external_mount_points =
      storage::ExternalMountPoints::GetSystemInstance();
  if (external_mount_points->GetVirtualPath(*entry_path, &virtual_path)) {
    *entry_path = std::move(virtual_path);
    return content::FileSystemAccessEntryFactory::PathType::kExternal;
  }
#endif
  return content::FileSystemAccessEntryFactory::PathType::kLocal;
}

}  // namespace

std::vector<blink::mojom::DataTransferFilePtr> FileInfosToDataTransferFiles(
    const std::vector<ui::FileInfo>& filenames,
    FileSystemAccessManagerImpl* file_system_access_manager,
    int child_id) {
  std::vector<blink::mojom::DataTransferFilePtr> result;
  for (const ui::FileInfo& file_info : filenames) {
    blink::mojom::DataTransferFilePtr file =
        blink::mojom::DataTransferFile::New();
    file->path = file_info.path;
    file->display_name = file_info.display_name;
    mojo::PendingRemote<blink::mojom::FileSystemAccessDataTransferToken>
        pending_token;
    base::FilePath entry_path = file_info.path;
    FileSystemAccessManagerImpl::PathType path_type =
        MaybeRemapPath(&entry_path);
    file_system_access_manager->CreateFileSystemAccessDataTransferToken(
        path_type, entry_path, child_id,
        pending_token.InitWithNewPipeAndPassReceiver());
    file->file_system_access_token = std::move(pending_token);
    result.push_back(std::move(file));
  }
  return result;
}

std::vector<blink::mojom::DragItemFileSystemFilePtr>
FileSystemFileInfosToDragItemFileSystemFilePtr(
    std::vector<DropData::FileSystemFileInfo> file_system_file_infos,
    FileSystemAccessManagerImpl* file_system_access_manager,
    scoped_refptr<content::ChromeBlobStorageContext> context) {
  std::vector<blink::mojom::DragItemFileSystemFilePtr> result;
  for (const content::DropData::FileSystemFileInfo& file_system_file :
       file_system_file_infos) {
    blink::mojom::DragItemFileSystemFilePtr item =
        blink::mojom::DragItemFileSystemFile::New();
    item->url = file_system_file.url;
    item->size = file_system_file.size;
    item->file_system_id = file_system_file.filesystem_id;

    storage::FileSystemURL file_system_url =
        file_system_access_manager->context()->CrackURLInFirstPartyContext(
            file_system_file.url);
    DCHECK(file_system_url.type() != storage::kFileSystemTypePersistent);
    DCHECK(file_system_url.type() != storage::kFileSystemTypeTemporary);

    std::string uuid = base::Uuid::GenerateRandomV4().AsLowercaseString();

    std::string content_type;

    base::FilePath::StringType extension = file_system_url.path().Extension();
    if (!extension.empty()) {
      std::string mime_type;
      // TODO(https://crbug.com/155455): Historically for blobs created from
      // file system URLs we've only considered well known content types to
      // avoid leaking the presence of locally installed applications when
      // creating blobs from files in the sandboxed file system. However, since
      // this code path should only deal with real/"trusted" paths, we could
      // consider taking platform defined mime type mappings into account here
      // as well. Note that the approach used here must not block or else it
      // can't be called from the UI thread (for example, calls to
      // GetMimeTypeFromExtension can block).
      if (net::GetWellKnownMimeTypeFromExtension(extension.substr(1),
                                                 &mime_type))
        content_type = std::move(mime_type);
    }
    // TODO(https://crbug.com/962306): Consider some kind of fallback type when
    // the above mime type detection fails.

    mojo::PendingRemote<blink::mojom::Blob> blob_remote;
    mojo::PendingReceiver<blink::mojom::Blob> blob_receiver =
        blob_remote.InitWithNewPipeAndPassReceiver();

    item->serialized_blob = blink::mojom::SerializedBlob::New(
        uuid, content_type, item->size, std::move(blob_remote));

    GetIOThreadTaskRunner({})->PostTask(
        FROM_HERE,
        base::BindOnce(
            &ChromeBlobStorageContext::CreateFileSystemBlob, context,
            base::WrapRefCounted(file_system_access_manager->context()),
            std::move(blob_receiver), std::move(file_system_url),
            std::move(uuid), std::move(content_type), item->size,
            base::Time()));

    result.push_back(std::move(item));
  }
  return result;
}

blink::mojom::DragDataPtr DropDataToDragData(
    const DropData& drop_data,
    FileSystemAccessManagerImpl* file_system_access_manager,
    int child_id,
    scoped_refptr<ChromeBlobStorageContext> chrome_blob_storage_context) {
  // These fields are currently unused when dragging into Blink.
  DCHECK(drop_data.download_metadata.empty());
  DCHECK(drop_data.file_contents_content_disposition.empty());

  std::vector<blink::mojom::DragItemPtr> items;
  if (drop_data.text) {
    blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New();
    item->string_type = ui::kMimeTypeText;
    item->string_data = *drop_data.text;
    items.push_back(blink::mojom::DragItem::NewString(std::move(item)));
  }
  if (!drop_data.url.is_empty()) {
    blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New();
    item->string_type = ui::kMimeTypeURIList;
    item->string_data = base::UTF8ToUTF16(drop_data.url.spec());
    item->title = drop_data.url_title;
    items.push_back(blink::mojom::DragItem::NewString(std::move(item)));
  }
  if (drop_data.html) {
    blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New();
    item->string_type = ui::kMimeTypeHTML;
    item->string_data = *drop_data.html;
    item->base_url = drop_data.html_base_url;
    items.push_back(blink::mojom::DragItem::NewString(std::move(item)));
  }
  std::vector<blink::mojom::DataTransferFilePtr> files =
      FileInfosToDataTransferFiles(drop_data.filenames,
                                   file_system_access_manager, child_id);
  for (auto& file : files) {
    items.push_back(blink::mojom::DragItem::NewFile(std::move(file)));
  }

  std::vector<blink::mojom::DragItemFileSystemFilePtr> file_system_files =
      FileSystemFileInfosToDragItemFileSystemFilePtr(
          drop_data.file_system_files, file_system_access_manager,
          std::move(chrome_blob_storage_context));
  for (auto& file_system_file : file_system_files) {
    items.push_back(
        blink::mojom::DragItem::NewFileSystemFile(std::move(file_system_file)));
  }
  if (drop_data.file_contents_source_url.is_valid()) {
    blink::mojom::DragItemBinaryPtr item = blink::mojom::DragItemBinary::New();
    item->data = mojo_base::BigBuffer(
        base::as_bytes(base::make_span(drop_data.file_contents)));
    item->is_image_accessible = drop_data.file_contents_image_accessible;
    item->source_url = drop_data.file_contents_source_url;
    item->filename_extension =
        base::FilePath(drop_data.file_contents_filename_extension);
    items.push_back(blink::mojom::DragItem::NewBinary(std::move(item)));
  }
  for (const std::pair<const std::u16string, std::u16string>& data :
       drop_data.custom_data) {
    blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New();
    item->string_type = base::UTF16ToUTF8(data.first);
    item->string_data = data.second;
    items.push_back(blink::mojom::DragItem::NewString(std::move(item)));
  }

  return blink::mojom::DragData::New(
      std::move(items),
      // While this shouldn't be a problem in production code, as the
      // real file_system_id should never be empty if used in browser to
      // renderer messages, some tests use this function to test renderer to
      // browser messages, in which case the field is unused and this will hit
      // a DCHECK.
      drop_data.filesystem_id.empty()
          ? absl::nullopt
          : absl::optional<std::string>(
                base::UTF16ToUTF8(drop_data.filesystem_id)),
      drop_data.referrer_policy);
}

blink::mojom::DragDataPtr DropMetaDataToDragData(
    const std::vector<DropData::Metadata>& drop_meta_data) {
  std::vector<blink::mojom::DragItemPtr> items;

  for (const auto& meta_data_item : drop_meta_data) {
    if (meta_data_item.kind == DropData::Kind::STRING) {
      blink::mojom::DragItemStringPtr item =
          blink::mojom::DragItemString::New();
      item->string_type = base::UTF16ToUTF8(meta_data_item.mime_type);
      // Have to pass a dummy URL here instead of an empty URL because the
      // DropData received by browser_plugins goes through a round trip:
      // DropData::MetaData --> WebDragData-->DropData. In the end, DropData
      // will contain an empty URL (which means no URL is dragged) if the URL in
      // WebDragData is empty.
      if (base::EqualsASCII(meta_data_item.mime_type, ui::kMimeTypeURIList)) {
        item->string_data = u"about:dragdrop-placeholder";
      }
      items.push_back(blink::mojom::DragItem::NewString(std::move(item)));
      continue;
    }

    // TODO(hush): crbug.com/584789. Blink needs to support creating a file with
    // just the mimetype. This is needed to drag files to WebView on Android
    // platform.
    if ((meta_data_item.kind == DropData::Kind::FILENAME) &&
        !meta_data_item.filename.empty()) {
      blink::mojom::DataTransferFilePtr item =
          blink::mojom::DataTransferFile::New();
      item->path = meta_data_item.filename;
      items.push_back(blink::mojom::DragItem::NewFile(std::move(item)));
      continue;
    }

    if (meta_data_item.kind == DropData::Kind::FILESYSTEMFILE) {
      blink::mojom::DragItemFileSystemFilePtr item =
          blink::mojom::DragItemFileSystemFile::New();
      item->url = meta_data_item.file_system_url;
      items.push_back(
          blink::mojom::DragItem::NewFileSystemFile(std::move(item)));
      continue;
    }

    if (meta_data_item.kind == DropData::Kind::BINARY) {
      blink::mojom::DragItemBinaryPtr item =
          blink::mojom::DragItemBinary::New();
      item->source_url = meta_data_item.file_contents_url;
      items.push_back(blink::mojom::DragItem::NewBinary(std::move(item)));
      continue;
    }
  }
  return blink::mojom::DragData::New(std::move(items), absl::nullopt,
                                     network::mojom::ReferrerPolicy::kDefault);
}

DropData DragDataToDropData(const blink::mojom::DragData& drag_data) {
  // This field should be empty when dragging from the renderer.
  DCHECK(!drag_data.file_system_id);

  DropData result;
  for (const blink::mojom::DragItemPtr& item : drag_data.items) {
    switch (item->which()) {
      case blink::mojom::DragItemDataView::Tag::kString: {
        const blink::mojom::DragItemStringPtr& string_item = item->get_string();
        std::string str_type = string_item->string_type;
        if (str_type == ui::kMimeTypeText) {
          result.text = string_item->string_data;
        } else if (str_type == ui::kMimeTypeURIList) {
          result.url = GURL(string_item->string_data);
          if (string_item->title)
            result.url_title = *string_item->title;
        } else if (str_type == ui::kMimeTypeDownloadURL) {
          result.download_metadata = string_item->string_data;
          result.referrer_policy = drag_data.referrer_policy;
        } else if (str_type == ui::kMimeTypeHTML) {
          result.html = string_item->string_data;
          if (string_item->base_url)
            result.html_base_url = *string_item->base_url;
        } else {
          result.custom_data.emplace(
              base::UTF8ToUTF16(string_item->string_type),
              string_item->string_data);
        }
        break;
      }
      case blink::mojom::DragItemDataView::Tag::kBinary: {
        DCHECK(result.file_contents.empty());

        const blink::mojom::DragItemBinaryPtr& binary_item = item->get_binary();
        base::span<const uint8_t> contents = base::make_span(binary_item->data);
        result.file_contents.assign(contents.begin(), contents.end());
        result.file_contents_image_accessible =
            binary_item->is_image_accessible;
        result.file_contents_source_url = binary_item->source_url;
        result.file_contents_filename_extension =
            binary_item->filename_extension.value();
        if (binary_item->content_disposition) {
          result.file_contents_content_disposition =
              *binary_item->content_disposition;
        }
        break;
      }
      case blink::mojom::DragItemDataView::Tag::kFile: {
        const blink::mojom::DataTransferFilePtr& file_item = item->get_file();
        // TODO(varunjain): This only works on chromeos. Support win/mac/gtk.
        result.filenames.emplace_back(file_item->path, file_item->display_name);
        break;
      }
      case blink::mojom::DragItemDataView::Tag::kFileSystemFile: {
        const blink::mojom::DragItemFileSystemFilePtr& file_system_file_item =
            item->get_file_system_file();
        // This field should be empty when dragging from the renderer.
        DCHECK(!file_system_file_item->file_system_id);

        DropData::FileSystemFileInfo info;
        info.url = file_system_file_item->url;
        info.size = file_system_file_item->size;
        info.filesystem_id = std::string();
        result.file_system_files.push_back(std::move(info));
        break;
      }
    }
  }
  return result;
}

}  // namespace content
