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

#include "chrome/browser/ash/fileapi/recent_disk_source.h"

#include <utility>

#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/mime_util.h"
#include "storage/browser/file_system/external_mount_points.h"
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_operation.h"
#include "storage/browser/file_system/file_system_operation_runner.h"
#include "storage/browser/file_system/file_system_url.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "ui/file_manager/file_types_data.h"
#include "url/origin.h"

using content::BrowserThread;

namespace ash {

namespace {

constexpr char kAudioMimeType[] = "audio/*";
constexpr char kImageMimeType[] = "image/*";
constexpr char kVideoMimeType[] = "video/*";

void OnReadDirectoryOnIOThread(
    const storage::FileSystemOperation::ReadDirectoryCallback& callback,
    base::File::Error result,
    storage::FileSystemOperation::FileEntryList entries,
    bool has_more) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  content::GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE,
      base::BindOnce(callback, result, std::move(entries), has_more));
}

void ReadDirectoryOnIOThread(
    scoped_refptr<storage::FileSystemContext> file_system_context,
    const storage::FileSystemURL& url,
    const storage::FileSystemOperation::ReadDirectoryCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  file_system_context->operation_runner()->ReadDirectory(
      url, base::BindRepeating(&OnReadDirectoryOnIOThread, callback));
}

void OnGetMetadataOnIOThread(
    storage::FileSystemOperation::GetMetadataCallback callback,
    base::File::Error result,
    const base::File::Info& info) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  content::GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE, base::BindOnce(std::move(callback), result, info));
}

void GetMetadataOnIOThread(
    scoped_refptr<storage::FileSystemContext> file_system_context,
    const storage::FileSystemURL& url,
    storage::FileSystemOperation::GetMetadataFieldSet fields,
    storage::FileSystemOperation::GetMetadataCallback callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  file_system_context->operation_runner()->GetMetadata(
      url, fields,
      base::BindOnce(&OnGetMetadataOnIOThread, std::move(callback)));
}

}  // namespace

RecentDiskSource::RecentDiskSource::CallContext::CallContext(
    const Params& params,
    GetRecentFilesCallback callback)
    : params(params),
      callback(std::move(callback)),
      build_start_time(base::TimeTicks::Now()),
      accumulator(params.max_files()) {}

RecentDiskSource::RecentDiskSource::CallContext::CallContext(
    CallContext&& context)
    : params(context.params),
      callback(std::move(context.callback)),
      build_start_time(context.build_start_time),
      inflight_readdirs(context.inflight_readdirs),
      inflight_stats(context.inflight_stats),
      accumulator(std::move(context.accumulator)) {}

RecentDiskSource::RecentDiskSource::CallContext::~CallContext() = default;

RecentDiskSource::RecentDiskSource(
    extensions::api::file_manager_private::VolumeType volume_type,
    std::string mount_point_name,
    bool ignore_dotfiles,
    int max_depth,
    std::string uma_histogram_name)
    : RecentSource(volume_type),
      mount_point_name_(std::move(mount_point_name)),
      ignore_dotfiles_(ignore_dotfiles),
      max_depth_(max_depth),
      uma_histogram_name_(std::move(uma_histogram_name)) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
}

RecentDiskSource::~RecentDiskSource() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
}

void RecentDiskSource::GetRecentFiles(const Params& params,
                                      GetRecentFilesCallback callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(context_map_.Lookup(params.call_id()) == nullptr);

  // Return immediately if mount point does not exist.
  storage::ExternalMountPoints* mount_points =
      storage::ExternalMountPoints::GetSystemInstance();
  base::FilePath path;
  if (!mount_points->GetRegisteredPath(mount_point_name_, &path)) {
    std::move(callback).Run({});
    return;
  }

  // Create a unique context for this call.
  auto context = std::make_unique<CallContext>(params, std::move(callback));
  context_map_.AddWithID(std::move(context), params.call_id());

  ScanDirectory(params.call_id(), base::FilePath(), 1);
}

std::vector<RecentFile> RecentDiskSource::Stop(const int32_t call_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  CallContext* context = context_map_.Lookup(call_id);
  if (context == nullptr) {
    // The Stop method was called after we already responded. Just return empty
    // list of files.
    return {};
  }
  // Proper stop; get the files and erase the context.
  const std::vector<RecentFile> files = context->accumulator.Get();
  context_map_.Remove(call_id);
  return files;
}

void RecentDiskSource::ScanDirectory(const int32_t call_id,
                                     const base::FilePath& path,
                                     int depth) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // If context is gone, that is Stop() has been called, exit immediately.
  CallContext* context = context_map_.Lookup(call_id);
  if (context == nullptr) {
    return;
  }

  storage::FileSystemURL url = BuildDiskURL(context->params, path);

  ++context->inflight_readdirs;
  content::GetIOThreadTaskRunner({})->PostTask(
      FROM_HERE,
      base::BindOnce(
          &ReadDirectoryOnIOThread,
          base::WrapRefCounted(context->params.file_system_context()), url,
          base::BindRepeating(&RecentDiskSource::OnReadDirectory,
                              weak_ptr_factory_.GetWeakPtr(), call_id, path,
                              depth)));
}

void RecentDiskSource::OnReadDirectory(
    const int32_t call_id,
    const base::FilePath& path,
    const int depth,
    base::File::Error result,
    storage::FileSystemOperation::FileEntryList entries,
    bool has_more) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  // If context is gone, that is Stop() has been called, exit immediately.
  CallContext* context = context_map_.Lookup(call_id);
  if (context == nullptr) {
    return;
  }

  const std::u16string q16 = base::UTF8ToUTF16(context->params.query());
  for (const auto& entry : entries) {
    // Ignore directories and files that start with dot.
    if (ignore_dotfiles_ &&
        base::StartsWith(entry.name.value(), ".",
                         base::CompareCase::INSENSITIVE_ASCII)) {
      continue;
    }
    base::FilePath subpath = path.Append(entry.name);

    if (entry.type == filesystem::mojom::FsFileType::DIRECTORY) {
      if ((max_depth_ > 0 && depth >= max_depth_) || context->params.IsLate()) {
        continue;
      }
      ScanDirectory(call_id, subpath, depth + 1);
    } else {
      if (!MatchesFileType(entry.name.path(), context->params.file_type())) {
        continue;
      }
      if (!FileNameMatches(base::UTF8ToUTF16(entry.name.value()), q16)) {
        continue;
      }
      storage::FileSystemURL url = BuildDiskURL(context->params, subpath);
      ++context->inflight_stats;
      content::GetIOThreadTaskRunner({})->PostTask(
          FROM_HERE,
          base::BindOnce(
              &GetMetadataOnIOThread,
              base::WrapRefCounted(context->params.file_system_context()), url,
              storage::FileSystemOperation::GetMetadataFieldSet(
                  {storage::FileSystemOperation::GetMetadataField::
                       kLastModified}),
              base::BindOnce(&RecentDiskSource::OnGotMetadata,
                             weak_ptr_factory_.GetWeakPtr(), call_id, url)));
    }
  }

  if (has_more) {
    return;
  }

  --context->inflight_readdirs;
  if (context->inflight_stats == 0 && context->inflight_readdirs == 0) {
    OnReadOrStatFinished(call_id);
  }
}

void RecentDiskSource::OnGotMetadata(const int32_t call_id,
                                     const storage::FileSystemURL& url,
                                     base::File::Error result,
                                     const base::File::Info& info) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  // If context is gone, that is Stop() has been called, exit immediately.
  CallContext* context = context_map_.Lookup(call_id);
  if (context == nullptr) {
    return;
  }

  if (result == base::File::FILE_OK &&
      info.last_modified >= context->params.cutoff_time()) {
    context->accumulator.Add(RecentFile(url, info.last_modified));
  }

  --context->inflight_stats;
  if (context->inflight_stats == 0 && context->inflight_readdirs == 0) {
    OnReadOrStatFinished(call_id);
  }
}

void RecentDiskSource::OnReadOrStatFinished(const int32_t call_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  CallContext* context = context_map_.Lookup(call_id);
  // If context is gone, that is Stop() has been called, exit immediately.
  if (context == nullptr) {
    return;
  }

  DCHECK(context->inflight_stats == 0);
  DCHECK(context->inflight_readdirs == 0);
  DCHECK(!context->build_start_time.is_null());

  // All reads/scans completed.
  UmaHistogramTimes(uma_histogram_name_,
                    base::TimeTicks::Now() - context->build_start_time);

  std::move(context->callback).Run(context->accumulator.Get());
  context_map_.Remove(call_id);
}

storage::FileSystemURL RecentDiskSource::BuildDiskURL(
    const Params& params,
    const base::FilePath& path) const {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  storage::ExternalMountPoints* mount_points =
      storage::ExternalMountPoints::GetSystemInstance();
  return mount_points->CreateExternalFileSystemURL(
      blink::StorageKey::CreateFirstParty(url::Origin::Create(params.origin())),
      mount_point_name_, path);
}

bool RecentDiskSource::MatchesFileType(const base::FilePath& path,
                                       RecentSource::FileType file_type) {
  if (file_type == RecentSource::FileType::kAll) {
    return true;
  }

  // File type for |path| is guessed by data generated from file_types.json5.
  // It guesses mime types based on file extensions, but it has a limited set
  // of file extensions.
  // TODO(fukino): It is better to have better coverage of file extensions to be
  // consistent with file-type detection on Android system. crbug.com/1034874.
  const auto ext = base::ToLowerASCII(path.Extension());
  if (!file_types_data::kExtensionToMIME.contains(ext)) {
    return false;
  }
  std::string mime_type = file_types_data::kExtensionToMIME.at(ext);

  switch (file_type) {
    case RecentSource::FileType::kAudio:
      return net::MatchesMimeType(kAudioMimeType, mime_type);
    case RecentSource::FileType::kImage:
      return net::MatchesMimeType(kImageMimeType, mime_type);
    case RecentSource::FileType::kVideo:
      return net::MatchesMimeType(kVideoMimeType, mime_type);
    case RecentSource::FileType::kDocument:
      return file_types_data::kDocumentMIMETypes.contains(mime_type);
    default:
      return false;
  }
}

}  // namespace ash
