// Copyright 2020 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 "content/browser/native_io/native_io_host.h"

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

#include "base/bind.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/task_runner.h"
#include "content/browser/native_io/native_io_context.h"
#include "content/browser/native_io/native_io_file_host.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "third_party/blink/public/mojom/native_io/native_io.mojom.h"

namespace content {

namespace {

bool IsValidNativeIONameCharacter(char name_char) {
  return base::IsAsciiLower(name_char) || base::IsAsciiDigit(name_char) ||
         name_char == '_';
}

bool IsValidNativeIOName(const std::string& name) {
  if (name.empty())
    return false;

  return std::all_of(name.begin(), name.end(), &IsValidNativeIONameCharacter);
}

base::FilePath GetNativeIOFilePath(const base::FilePath& root_path,
                                   const std::string& name) {
  DCHECK(IsValidNativeIOName(name));

  // This simple implementation assumes that the name doesn't have any special
  // meaning to the host operating system.
  base::FilePath file_path = root_path.AppendASCII(name);
  DCHECK(root_path.IsParent(file_path));
  return file_path;
}

// Creates a task runner suitable for running file I/O tasks.
scoped_refptr<base::TaskRunner> CreateFileTaskRunner() {
  // We use a SequencedTaskRunner so that there is a global ordering to an
  // origin's directory operations.
  return base::CreateSequencedTaskRunner({
      // Needed for file I/O.
      base::MayBlock(),
      base::ThreadPool(),

      // Reasonable compromise, given that a few database operations are
      // blocking, while most operations are not. We should be able to do better
      // when we get scheduling APIs on the Web Platform.
      base::TaskPriority::USER_VISIBLE,

      // BLOCK_SHUTDOWN is definitely not appropriate. We might be able to move
      // to CONTINUE_ON_SHUTDOWN after very careful analysis.
      base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
  });
}

// Performs the file I/O work in OpenFile().
base::File DoOpenFile(const base::FilePath& root_path,
                      const std::string& name) {
  DCHECK(IsValidNativeIOName(name));

  // Lazily create the origin's directory.
  base::File::Error error;
  if (!base::CreateDirectoryAndGetError(root_path, &error))
    return base::File();

  return base::File(GetNativeIOFilePath(root_path, name),
                    base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
                        base::File::FLAG_WRITE | base::File::FLAG_SHARE_DELETE);
}

// Performs the file I/O work in DeleteFile().
bool DoDeleteFile(const base::FilePath& root_path, const std::string& name) {
  DCHECK(IsValidNativeIOName(name));

  // If the origin's directory wasn't created yet, there's nothing to delete.
  if (!base::PathExists(root_path))
    return true;

  return base::DeleteFile(GetNativeIOFilePath(root_path, name),
                          /*recursive=*/false);
}

using GetAllFileNamesResult =
    std::pair<base::File::Error, std::vector<std::string>>;

// Performs the file I/O work in GetAllFileNames().
GetAllFileNamesResult DoGetAllFileNames(const base::FilePath& root_path) {
  std::vector<std::string> result;

  // If the origin's directory wasn't created yet, there's no file to report.
  if (!base::PathExists(root_path))
    return {base::File::FILE_OK, std::move(result)};

  base::FileEnumerator file_enumerator(
      root_path, /*recursive=*/false, base::FileEnumerator::FILES,
      /*pattern=*/base::FilePath::StringType(),
      base::FileEnumerator::FolderSearchPolicy::ALL,
      base::FileEnumerator::ErrorPolicy::STOP_ENUMERATION);

  // TODO(pwnall): The result vector can grow to an unbounded size. Add a limit
  //               parameter with a reasonable upper bound.

  for (base::FilePath file_path = file_enumerator.Next(); !file_path.empty();
       file_path = file_enumerator.Next()) {
    // If the file name has a non-ASCII character, |file_name| will be the empty
    // string. This will correctly be flagged as corruption by the check below.
    std::string file_name = file_path.BaseName().MaybeAsASCII();

    // Chrome's NativeIO implementation only creates files that have valid
    // NativeIO names. Any other file names imply directory corruption.
    if (!IsValidNativeIOName(file_name)) {
      // TODO(pwnall): Figure out the corruption handling strategy. We could
      //               silently ignore the corrupted file, delete it, or stop
      //               and report an error.
      continue;
    }
    result.push_back(std::move(file_name));
  }

  // Don't return a partial list of files if an error occurred. The partial list
  // isn't meaningful, and may be useful information for a compromised renderer.
  //
  // TODO(pwnall): Reconsider this if we end up making NativeIO unusually
  //               friendly to corruption recovery.
  base::File::Error enumeration_error = file_enumerator.GetError();
  if (enumeration_error != base::File::FILE_OK)
    result.clear();

  return {enumeration_error, std::move(result)};
}

// Reports the result of the file I/O work in GetAllFileNames().
void DidGetAllFileNames(
    blink::mojom::NativeIOHost::GetAllFileNamesCallback callback,
    GetAllFileNamesResult result) {
  std::move(callback).Run(result.first == base::File::FILE_OK,
                          std::move(result.second));
}

}  // namespace

NativeIOHost::NativeIOHost(NativeIOContext* context,
                           const url::Origin& origin,
                           base::FilePath root_path)
    : root_path_(std::move(root_path)),
      context_(context),
      origin_(origin),
      file_task_runner_(CreateFileTaskRunner()) {
  DCHECK(!root_path_.empty());
  DCHECK(context != nullptr);

  // base::Unretained is safe here because this NativeIOHost owns |receivers_|.
  // So, the unretained NativeIOHost is guaranteed to outlive |receivers_| and
  // the closure that it uses.
  receivers_.set_disconnect_handler(base::BindRepeating(
      &NativeIOHost::OnReceiverDisconnect, base::Unretained(this)));
}

NativeIOHost::~NativeIOHost() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

void NativeIOHost::BindReceiver(
    mojo::PendingReceiver<blink::mojom::NativeIOHost> receiver) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  receivers_.Add(this, std::move(receiver));
}

void NativeIOHost::OpenFile(
    const std::string& name,
    mojo::PendingReceiver<blink::mojom::NativeIOFileHost> file_host_receiver,
    OpenFileCallback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!IsValidNativeIOName(name)) {
    mojo::ReportBadMessage("Invalid file name");
    std::move(callback).Run(base::File());
    return;
  }

  if (open_file_hosts_.find(name) != open_file_hosts_.end()) {
    // TODO(pwnall): Report that the file is locked.
    std::move(callback).Run(base::File());
    return;
  }

  auto insert_result = io_pending_files_.insert(name);
  bool insert_success = insert_result.second;
  if (!insert_success) {
    // TODO(pwnall): Report that the file is locked.
    std::move(callback).Run(base::File());
    return;
  }

  file_task_runner_->PostTaskAndReplyWithResult(
      FROM_HERE, base::BindOnce(&DoOpenFile, root_path_, name),
      base::BindOnce(&NativeIOHost::DidOpenFile, weak_factory_.GetWeakPtr(),
                     name, std::move(file_host_receiver), std::move(callback)));
}

void NativeIOHost::DeleteFile(const std::string& name,
                              DeleteFileCallback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!IsValidNativeIOName(name)) {
    mojo::ReportBadMessage("Invalid file name");
    std::move(callback).Run(false);
    return;
  }

  if (open_file_hosts_.find(name) != open_file_hosts_.end()) {
    // TODO(pwnall): Report that the file is locked.
    std::move(callback).Run(false);
    return;
  }

  auto insert_result = io_pending_files_.insert(name);
  bool insert_success = insert_result.second;
  if (!insert_success) {
    // TODO(pwnall): Report that the file is locked.
    std::move(callback).Run(false);
    return;
  }

  file_task_runner_->PostTaskAndReplyWithResult(
      FROM_HERE, base::BindOnce(&DoDeleteFile, root_path_, name),
      base::BindOnce(&NativeIOHost::DidDeleteFile, weak_factory_.GetWeakPtr(),
                     name, std::move(callback)));
}

void NativeIOHost::GetAllFileNames(GetAllFileNamesCallback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  file_task_runner_->PostTaskAndReplyWithResult(
      FROM_HERE, base::BindOnce(&DoGetAllFileNames, root_path_),
      base::BindOnce(&DidGetAllFileNames, std::move(callback)));
}

void NativeIOHost::OnFileClose(NativeIOFileHost* file_host) {
  DCHECK(open_file_hosts_.count(file_host->file_name()) > 0);
  DCHECK_EQ(open_file_hosts_[file_host->file_name()].get(), file_host);

  open_file_hosts_.erase(file_host->file_name());
}

void NativeIOHost::OnReceiverDisconnect() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  context_->OnHostReceiverDisconnect(this);
}

void NativeIOHost::DidOpenFile(
    const std::string& name,
    mojo::PendingReceiver<blink::mojom::NativeIOFileHost> file_host_receiver,
    OpenFileCallback callback,
    base::File file) {
  DCHECK(io_pending_files_.count(name));
  DCHECK(!open_file_hosts_.count(name));
  io_pending_files_.erase(name);

  if (!file.IsValid()) {
    std::move(callback).Run(std::move(file));
    return;
  }

  open_file_hosts_.insert(
      {name, std::make_unique<NativeIOFileHost>(std::move(file_host_receiver),
                                                this, name)});

  std::move(callback).Run(std::move(file));
  return;
}

void NativeIOHost::DidDeleteFile(const std::string& name,
                                 DeleteFileCallback callback,
                                 bool success) {
  DCHECK(io_pending_files_.count(name));
  DCHECK(!open_file_hosts_.count(name));
  io_pending_files_.erase(name);

  std::move(callback).Run(success);
  return;
}

}  // namespace content
