// Copyright 2020 The Chromium OS 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 "cryptohome/fake_platform.h"

#include <map>
#include <memory>
#include <optional>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/fs.h>
#include <vector>

#include <base/check.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <brillo/blkdev_utils/loop_device_fake.h>
#include <brillo/cryptohome.h>
#include <brillo/secure_blob.h>

#include "cryptohome/util/get_random_suffix.h"

#include "cryptohome/fake_platform/test_file_path.h"
#include "cryptohome/filesystem_layout.h"

namespace cryptohome {

using fake_platform::NormalizePath;

namespace {

class ProxyFileEnumerator : public FileEnumerator {
 public:
  ProxyFileEnumerator(const base::FilePath& original_path,
                      FakePlatform* fake_platform,
                      FakeMountMapper* fake_mount_mapper,
                      FileEnumerator* real_enumerator)
      : original_path_(NormalizePath(original_path)),
        fake_platform_(fake_platform),
        fake_mount_mapper_(fake_mount_mapper),
        real_enumerator_(real_enumerator) {}

  // Removed tmpfs prefix from the returned path.
  base::FilePath Next() override {
    base::FilePath next = real_enumerator_->Next();
    last_path_ = fake_mount_mapper_->ReverseResolvePath(next, original_path_);
    return last_path_;
  }

  FileEnumerator::FileInfo GetInfo() override {
    FileEnumerator::FileInfo real_info = real_enumerator_->GetInfo();
    base::stat_wrapper_t stat;
    CHECK(fake_platform_->Stat(last_path_, &stat));
    return FileEnumerator::FileInfo(real_info.GetName(), stat);
  }

 private:
  base::FilePath original_path_;
  FakePlatform* fake_platform_;
  FakeMountMapper* fake_mount_mapper_;
  std::unique_ptr<FileEnumerator> real_enumerator_;
  base::FilePath last_path_;
};

template <typename KeyType>
void RemoveFakeEntriesRecursiveImpl(
    const base::FilePath& path,
    std::unordered_map<base::FilePath, KeyType>* m) {
  for (auto it = m->begin(); it != m->end();) {
    auto tmp_it = it;
    ++it;
    if (tmp_it->first == path || path.IsParent(tmp_it->first)) {
      m->erase(tmp_it);
    }
  }
}

}  // namespace

// FakeExtendedAttributes

bool FakePlatform::FakeExtendedAttributes::Exists(
    const std::string& name) const {
  return xattrs_.find(name) != xattrs_.end();
}

void FakePlatform::FakeExtendedAttributes::List(
    std::vector<std::string>* attr_list) const {
  DCHECK(attr_list);
  attr_list->clear();
  for (const auto& xattr : xattrs_) {
    attr_list->push_back(xattr.first);
  }
}

bool FakePlatform::FakeExtendedAttributes::GetAsString(
    const std::string& name, std::string* value) const {
  const auto it = xattrs_.find(name);
  if (it == xattrs_.end()) {
    return false;
  }

  value->assign(it->second.data(), it->second.size());
  return true;
}

bool FakePlatform::FakeExtendedAttributes::Get(const std::string& name,
                                               char* value,
                                               ssize_t size) const {
  const auto it = xattrs_.find(name);
  if (it == xattrs_.end()) {
    return false;
  }

  if (it->second.size() > size) {
    return false;
  }

  memcpy(value, it->second.data(), it->second.size());

  return true;
}

void FakePlatform::FakeExtendedAttributes::Set(const std::string& name,
                                               const char* value,
                                               ssize_t size) {
  xattrs_[name].assign(value, value + size);
}

void FakePlatform::FakeExtendedAttributes::Remove(const std::string& name) {
  xattrs_.erase(name);
}

// Constructor/destructor

FakePlatform::FakePlatform()
    : Platform(),
      fake_loop_device_manager_(
          std::make_unique<brillo::fake::FakeLoopDeviceManager>()) {
  base::GetTempDir(&tmpfs_rootfs_);
  tmpfs_rootfs_ = tmpfs_rootfs_.Append(GetRandomSuffix());
  if (!real_platform_.CreateDirectory(tmpfs_rootfs_)) {
    LOG(ERROR) << "Failed to create test dir: " << tmpfs_rootfs_;
  }
  fake_mount_mapper_.reset(new FakeMountMapper(tmpfs_rootfs_));
  brillo::SecureBlob system_salt;
  InitializeFilesystemLayout(this, &system_salt);
  SetSystemSaltForLibbrillo(system_salt);
}

FakePlatform::~FakePlatform() {
  RemoveSystemSaltForLibbrillo();
  real_platform_.DeletePathRecursively(tmpfs_rootfs_);
}

// Helpers

base::FilePath FakePlatform::TestFilePath(const base::FilePath& path) const {
  CHECK(path.IsAbsolute());
  const base::FilePath normalized_path = NormalizePath(path);
  return fake_mount_mapper_->ResolvePath(normalized_path);
}

base::FilePath FakePlatform::StripTestFilePath(
    const base::FilePath& path) const {
  return fake_platform::StripTestFilePath(tmpfs_rootfs_, path);
}

bool FakePlatform::IsLink(const base::FilePath& path) const {
  return base::IsLink(TestFilePath(path));
}

void FakePlatform::RemoveFakeEntries(const base::FilePath& path) {
  base::AutoLock lock(mappings_lock_);
  xattrs_.erase(path);
  file_owners_.erase(path);
  file_mode_.erase(path);
  file_flags_.erase(path);
}

void FakePlatform::RemoveFakeEntriesRecursive(const base::FilePath& path) {
  base::AutoLock lock(mappings_lock_);
  RemoveFakeEntriesRecursiveImpl(path, &xattrs_);
  RemoveFakeEntriesRecursiveImpl(path, &file_owners_);
  RemoveFakeEntriesRecursiveImpl(path, &file_mode_);
  RemoveFakeEntriesRecursiveImpl(path, &file_flags_);
}

// Platform API

brillo::LoopDeviceManager* FakePlatform::GetLoopDeviceManager() {
  return fake_loop_device_manager_.get();
}

bool FakePlatform::Rename(const base::FilePath& from,
                          const base::FilePath& to) {
  return real_platform_.Rename(TestFilePath(from), TestFilePath(to));
}

bool FakePlatform::Move(const base::FilePath& from, const base::FilePath& to) {
  return real_platform_.Move(TestFilePath(from), TestFilePath(to));
}

bool FakePlatform::Copy(const base::FilePath& from, const base::FilePath& to) {
  return real_platform_.Copy(TestFilePath(from), TestFilePath(to));
}

bool FakePlatform::EnumerateDirectoryEntries(
    const base::FilePath& path,
    bool recursive,
    std::vector<base::FilePath>* ent_list) {
  return real_platform_.EnumerateDirectoryEntries(TestFilePath(path), recursive,
                                                  ent_list);
}

bool FakePlatform::IsDirectoryEmpty(const base::FilePath& path) {
  return real_platform_.IsDirectoryEmpty(TestFilePath(path));
}

bool FakePlatform::TouchFileDurable(const base::FilePath& path) {
  return real_platform_.TouchFileDurable(TestFilePath(path));
}

bool FakePlatform::DeleteFile(const base::FilePath& path) {
  RemoveFakeEntries(path);
  return real_platform_.DeleteFile(TestFilePath(path));
}

bool FakePlatform::DeletePathRecursively(const base::FilePath& path) {
  RemoveFakeEntriesRecursive(path);
  return real_platform_.DeletePathRecursively(TestFilePath(path));
}

bool FakePlatform::DeleteFileDurable(const base::FilePath& path) {
  RemoveFakeEntries(path);
  return real_platform_.DeleteFileDurable(TestFilePath(path));
}

bool FakePlatform::FileExists(const base::FilePath& path) const {
  return real_platform_.FileExists(TestFilePath(path));
}

bool FakePlatform::DirectoryExists(const base::FilePath& path) {
  return real_platform_.DirectoryExists(TestFilePath(path));
}

int FakePlatform::Access(const base::FilePath& path, uint32_t flag) {
  if (!FileExists(path)) {
    return -1;
  }

  mode_t mode;
  if (!GetPermissions(path, &mode)) {
    return -1;
  }
  bool failed_read = (flag & R_OK) && !(mode & S_IRUSR);
  bool failed_write = (flag & W_OK) && !(mode & S_IWUSR);
  bool failed_exec = (flag & X_OK) && !(mode & S_IXUSR);
  if (failed_read || failed_write || failed_exec) {
    return -1;
  }

  return 0;
}

bool FakePlatform::CreateDirectory(const base::FilePath& path) {
  return real_platform_.CreateDirectory(TestFilePath(path));
}

bool FakePlatform::CreateSparseFile(const base::FilePath& path, int64_t size) {
  return real_platform_.CreateSparseFile(TestFilePath(path), size);
}

bool FakePlatform::DataSyncFile(const base::FilePath& path) {
  return real_platform_.DataSyncFile(TestFilePath(path));
}

bool FakePlatform::SyncFile(const base::FilePath& path) {
  return real_platform_.SyncFile(TestFilePath(path));
}

bool FakePlatform::SyncDirectory(const base::FilePath& path) {
  return real_platform_.SyncDirectory(TestFilePath(path));
}

void FakePlatform::Sync() {
  real_platform_.Sync();
}

bool FakePlatform::CreateSymbolicLink(const base::FilePath& path,
                                      const base::FilePath& target) {
  if (target.IsAbsolute()) {
    return real_platform_.CreateSymbolicLink(TestFilePath(path),
                                             TestFilePath(target));
  } else {
    return real_platform_.CreateSymbolicLink(TestFilePath(path), target);
  }
}

bool FakePlatform::ReadLink(const base::FilePath& path,
                            base::FilePath* target) {
  base::FilePath tmp_path;
  if (!real_platform_.ReadLink(TestFilePath(path), &tmp_path)) {
    return false;
  }

  *target = StripTestFilePath(tmp_path);
  return true;
}

bool FakePlatform::SetFileTimes(const base::FilePath& path,
                                const struct timespec& atime,
                                const struct timespec& mtime,
                                bool follow_links) {
  return real_platform_.SetFileTimes(TestFilePath(path), atime, mtime,
                                     follow_links);
}

bool FakePlatform::SendFile(int fd_to,
                            int fd_from,
                            off_t offset,
                            size_t count) {
  return real_platform_.SendFile(fd_to, fd_from, offset, count);
}

void FakePlatform::InitializeFile(base::File* file,
                                  const base::FilePath& path,
                                  uint32_t flags) {
  // This part here is to make one of the access verification tests happy.
  // TODO(dlunev): generalize access control abiding fake permissions.
  if (FileExists(path)) {
    mode_t mode;
    CHECK(GetPermissions(path, &mode));
    bool init_for_read = flags & base::File::FLAG_READ;
    bool can_read = mode & S_IRUSR;
    if (init_for_read && !can_read) {
      return;
    }
  }

  real_platform_.InitializeFile(file, TestFilePath(path), flags);
}

bool FakePlatform::LockFile(int fd) {
  return real_platform_.LockFile(fd);
}

bool FakePlatform::ReadFile(const base::FilePath& path, brillo::Blob* blob) {
  return real_platform_.ReadFile(TestFilePath(path), blob);
}

bool FakePlatform::ReadFileToString(const base::FilePath& path,
                                    std::string* str) {
  return real_platform_.ReadFileToString(TestFilePath(path), str);
}

bool FakePlatform::ReadFileToSecureBlob(const base::FilePath& path,
                                        brillo::SecureBlob* sblob) {
  return real_platform_.ReadFileToSecureBlob(TestFilePath(path), sblob);
}

bool FakePlatform::WriteFile(const base::FilePath& path,
                             const brillo::Blob& blob) {
  return real_platform_.WriteFile(TestFilePath(path), blob);
}

bool FakePlatform::WriteSecureBlobToFile(const base::FilePath& path,
                                         const brillo::SecureBlob& sblob) {
  return real_platform_.WriteSecureBlobToFile(TestFilePath(path), sblob);
}

bool FakePlatform::WriteFileAtomic(const base::FilePath& path,
                                   const brillo::Blob& blob,
                                   mode_t mode) {
  return real_platform_.WriteFileAtomic(TestFilePath(path), blob, mode);
}

bool FakePlatform::WriteSecureBlobToFileAtomic(const base::FilePath& path,
                                               const brillo::SecureBlob& sblob,
                                               mode_t mode) {
  return real_platform_.WriteSecureBlobToFileAtomic(TestFilePath(path), sblob,
                                                    mode);
}

bool FakePlatform::WriteFileAtomicDurable(const base::FilePath& path,
                                          const brillo::Blob& blob,
                                          mode_t mode) {
  return real_platform_.WriteFileAtomicDurable(TestFilePath(path), blob, mode);
}

bool FakePlatform::WriteSecureBlobToFileAtomicDurable(
    const base::FilePath& path, const brillo::SecureBlob& sblob, mode_t mode) {
  return real_platform_.WriteSecureBlobToFileAtomicDurable(TestFilePath(path),
                                                           sblob, mode);
}

bool FakePlatform::WriteStringToFile(const base::FilePath& path,
                                     const std::string& str) {
  return real_platform_.WriteStringToFile(TestFilePath(path), str);
}

bool FakePlatform::WriteStringToFileAtomicDurable(const base::FilePath& path,
                                                  const std::string& str,
                                                  mode_t mode) {
  return real_platform_.WriteStringToFileAtomicDurable(TestFilePath(path), str,
                                                       mode);
}

bool FakePlatform::WriteArrayToFile(const base::FilePath& path,
                                    const char* data,
                                    size_t size) {
  return real_platform_.WriteArrayToFile(TestFilePath(path), data, size);
}

FILE* FakePlatform::OpenFile(const base::FilePath& path, const char* mode) {
  return real_platform_.OpenFile(TestFilePath(path), mode);
}

bool FakePlatform::CloseFile(FILE* file) {
  return real_platform_.CloseFile(file);
}

FileEnumerator* FakePlatform::GetFileEnumerator(const base::FilePath& path,
                                                bool recursive,
                                                int file_type) {
  return new ProxyFileEnumerator(path, this, fake_mount_mapper_.get(),
                                 real_platform_.GetFileEnumerator(
                                     TestFilePath(path), recursive, file_type));
}

bool FakePlatform::GetFileSize(const base::FilePath& path, int64_t* size) {
  return real_platform_.GetFileSize(TestFilePath(path), size);
}

bool FakePlatform::Stat(const base::FilePath& path, base::stat_wrapper_t* buf) {
  if (!real_platform_.Stat(TestFilePath(path), buf)) {
    return false;
  }
  // Override mode and ownership from internal fake mappings.
  mode_t mode;
  if (!GetPermissions(path, &mode)) {
    return false;
  }
  buf->st_mode &= ~01777;
  buf->st_mode |= mode;
  if (!GetOwnership(path, &buf->st_uid, &buf->st_gid, false)) {
    return false;
  }
  return true;
}

bool FakePlatform::StatVFS(const base::FilePath& path, struct statvfs* vfs) {
  return real_platform_.StatVFS(TestFilePath(path), vfs);
}

bool FakePlatform::HasExtendedFileAttribute(const base::FilePath& path,
                                            const std::string& name) {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  const auto it = xattrs_.find(real_path);
  if (it == xattrs_.end() || !it->second.Exists(name)) {
    // Client code checks the error code, so set it.
    errno = ENODATA;
    return false;
  }

  return true;
}

bool FakePlatform::ListExtendedFileAttributes(
    const base::FilePath& path, std::vector<std::string>* attr_list) {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  const auto it = xattrs_.find(real_path);
  if (it == xattrs_.end()) {
    attr_list->clear();
    return true;
  }

  it->second.List(attr_list);
  return true;
}

bool FakePlatform::GetExtendedFileAttributeAsString(const base::FilePath& path,
                                                    const std::string& name,
                                                    std::string* value) {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  const auto it = xattrs_.find(real_path);
  if (it == xattrs_.end() || !it->second.Exists(name)) {
    // Client code checks the error code, so set it.
    errno = ENODATA;
    return false;
  }

  return it->second.GetAsString(name, value);
}

bool FakePlatform::GetExtendedFileAttribute(const base::FilePath& path,
                                            const std::string& name,
                                            char* value,
                                            ssize_t size) {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  const auto it = xattrs_.find(real_path);
  if (it == xattrs_.end() || !it->second.Exists(name)) {
    // Client code checks the error code, so set it.
    errno = ENODATA;
    return false;
  }

  return it->second.Get(name, value, size);
}

bool FakePlatform::SetExtendedFileAttribute(const base::FilePath& path,
                                            const std::string& name,
                                            const char* value,
                                            size_t size) {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }

  auto [it, unused] =
      xattrs_.emplace(real_path, FakePlatform::FakeExtendedAttributes());

  it->second.Set(name, value, size);
  return true;
}

bool FakePlatform::RemoveExtendedFileAttribute(const base::FilePath& path,
                                               const std::string& name) {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  auto it = xattrs_.find(real_path);
  if (it == xattrs_.end()) {
    return true;
  }

  it->second.Remove(name);
  return true;
}

bool FakePlatform::GetExtFileAttributes(const base::FilePath& path,
                                        int* flags) {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  auto it = file_flags_.find(real_path);
  if (it == file_flags_.end()) {
    *flags = 0;
    return true;
  }
  *flags = it->second;
  return true;
}

bool FakePlatform::SetExtFileAttributes(const base::FilePath& path, int flags) {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  file_flags_[real_path] = flags;
  return true;
}

bool FakePlatform::HasNoDumpFileAttribute(const base::FilePath& path) {
  int flags;
  return GetExtFileAttributes(path, &flags) &&
         (flags & FS_NODUMP_FL) == FS_NODUMP_FL;
}

bool FakePlatform::GetOwnership(const base::FilePath& path,
                                uid_t* user_id,
                                gid_t* group_id,
                                bool follow_links) const {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  // Can not do it at present due to weird test dependencies.
  if (file_owners_.find(real_path) == file_owners_.end()) {
    *user_id = kChronosUid;
    *group_id = kChronosGid;
    return true;
  }

  *user_id = file_owners_.at(real_path).first;
  *group_id = file_owners_.at(real_path).second;
  return true;
}

bool FakePlatform::SetOwnership(const base::FilePath& path,
                                uid_t user_id,
                                gid_t group_id,
                                bool follow_links) const {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  file_owners_[real_path] = {user_id, group_id};
  return true;
}

bool FakePlatform::SafeDirChown(const base::FilePath& path,
                                uid_t user_id,
                                gid_t group_id) {
  if (!DirectoryExists(path)) {
    return false;
  }
  return SetOwnership(path, user_id, group_id, false);
}

bool FakePlatform::GetPermissions(const base::FilePath& path,
                                  mode_t* mode) const {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  if (file_mode_.find(real_path) == file_mode_.end()) {
    (*mode) = S_IRWXU | S_IRGRP | S_IXGRP;
    return true;
  }
  (*mode) = (file_mode_.at(real_path) & 01777);
  return true;
}

bool FakePlatform::SetPermissions(const base::FilePath& path,
                                  mode_t mode) const {
  base::AutoLock lock(mappings_lock_);
  const base::FilePath real_path = TestFilePath(path);
  if (!IsLink(path) && !FileExists(path)) {
    return false;
  }
  file_mode_[real_path] = mode & 01777;
  return true;
}

bool FakePlatform::SafeDirChmod(const base::FilePath& path, mode_t mode) {
  if (!DirectoryExists(path)) {
    return false;
  }
  return SetPermissions(path, mode);
}

bool FakePlatform::SafeCreateDirAndSetOwnershipAndPermissions(
    const base::FilePath& path, mode_t mode, uid_t user_id, gid_t gid) {
  if (!CreateDirectory(path) || !SafeDirChown(path, user_id, gid) ||
      !SafeDirChmod(path, mode)) {
    return false;
  }
  return true;
}

bool FakePlatform::SafeCreateDirAndSetOwnership(const base::FilePath& path,
                                                uid_t user_id,
                                                gid_t gid) {
  if (!CreateDirectory(path) || !SafeDirChown(path, user_id, gid)) {
    return false;
  }
  return true;
}

int64_t FakePlatform::AmountOfFreeDiskSpace(const base::FilePath& path) const {
  return real_platform_.AmountOfFreeDiskSpace(TestFilePath(path));
}

bool FakePlatform::Mount(const base::FilePath& from,
                         const base::FilePath& to,
                         const std::string& type,
                         uint32_t mount_flags,
                         const std::string& mount_options) {
  base::FilePath nfrom = NormalizePath(from);
  base::FilePath nto = NormalizePath(to);
  if (type == "ecryptfs") {
    // In the case of ecryptfs we more or less transparently overlay
    // directories, so it looks more like a bind rather than a mount.
    return fake_mount_mapper_->Bind(nfrom, nto);
  }
  return fake_mount_mapper_->Mount(nfrom, nto);
}

bool FakePlatform::Bind(const base::FilePath& from,
                        const base::FilePath& to,
                        RemountOption remount,
                        bool nosymfollow) {
  base::FilePath nfrom = NormalizePath(from);
  base::FilePath nto = NormalizePath(to);
  return fake_mount_mapper_->Bind(nfrom, nto);
}

bool FakePlatform::Unmount(const base::FilePath& path,
                           bool lazy,
                           bool* was_busy) {
  base::FilePath normalized_path = NormalizePath(path);
  bool ok = fake_mount_mapper_->Unmount(normalized_path);
  if (was_busy != nullptr) {
    *was_busy = !ok;
  }
  return true;
}

void FakePlatform::LazyUnmount(const base::FilePath& path) {
  base::FilePath normalized_path = NormalizePath(path);
  // TODO(dlunev): actually implement lazy unmount in fake mapper, for now busy
  // target will just fail silently.
  (void)fake_mount_mapper_->Unmount(normalized_path);
}

bool FakePlatform::GetLoopDeviceMounts(
    std::multimap<const base::FilePath, const base::FilePath>* mounts) {
  constexpr char kLoopPrefix[] = "/dev/loop";
  fake_mount_mapper_->ListMountsBySourcePrefix(kLoopPrefix, mounts);
  return true;
}

bool FakePlatform::GetMountsBySourcePrefix(
    const base::FilePath& from_prefix,
    std::multimap<const base::FilePath, const base::FilePath>* mounts) {
  fake_mount_mapper_->ListMountsBySourcePrefix(from_prefix, mounts);
  return true;
}

bool FakePlatform::IsDirectoryMounted(const base::FilePath& directory) {
  const base::FilePath ndirectory = NormalizePath(directory);
  return fake_mount_mapper_->IsMounted(ndirectory);
}

std::optional<std::vector<bool>> FakePlatform::AreDirectoriesMounted(
    const std::vector<base::FilePath>& directories) {
  std::vector<bool> result;
  result.reserve(directories.size());
  for (const auto& d : directories) {
    result.push_back(IsDirectoryMounted(d));
  }
  return result;
}

// Test API

void FakePlatform::SetSystemSaltForLibbrillo(const brillo::SecureBlob& salt) {
  DCHECK(!old_salt_);
  std::string* brillo_salt = new std::string();
  brillo_salt->resize(salt.size());
  brillo_salt->assign(reinterpret_cast<const char*>(salt.data()), salt.size());
  old_salt_ = brillo::cryptohome::home::GetSystemSalt();
  brillo::cryptohome::home::SetSystemSalt(brillo_salt);
}

void FakePlatform::RemoveSystemSaltForLibbrillo() {
  std::string* salt = brillo::cryptohome::home::GetSystemSalt();
  brillo::cryptohome::home::SetSystemSalt(old_salt_);
  delete salt;
  old_salt_ = nullptr;
}

}  // namespace cryptohome
