// Copyright 2018 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 "cros-disks/fuse_mount_manager.h"

#include <sys/mount.h>

#include <utility>

#include <base/check.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <brillo/process/process_reaper.h>

#include "cros-disks/drivefs_helper.h"
#include "cros-disks/error_logger.h"
#include "cros-disks/fuse_mounter.h"
#include "cros-disks/fusebox_helper.h"
#include "cros-disks/platform.h"
#include "cros-disks/quote.h"
#include "cros-disks/smbfs_helper.h"
#include "cros-disks/sshfs_helper.h"
#include "cros-disks/uri.h"

namespace cros_disks {

FUSEMountManager::FUSEMountManager(const std::string& mount_root,
                                   const std::string& working_dirs_root,
                                   Platform* platform,
                                   Metrics* metrics,
                                   brillo::ProcessReaper* process_reaper)
    : MountManager(mount_root, platform, metrics, process_reaper),
      working_dirs_root_(working_dirs_root) {}

FUSEMountManager::~FUSEMountManager() {
  UnmountAll();
}

bool FUSEMountManager::Initialize() {
  if (!MountManager::Initialize())
    return false;

  if (!platform()->CreateDirectory(working_dirs_root_)) {
    PLOG(ERROR) << "Cannot create writable FUSE directory "
                << quote(working_dirs_root_);
    return false;
  }

  if (!platform()->SetOwnership(working_dirs_root_, getuid(), getgid()) ||
      !platform()->SetPermissions(working_dirs_root_, 0755)) {
    PLOG(ERROR) << "Cannot set up writable FUSE directory "
                << quote(working_dirs_root_);
    return false;
  }

  // Register specific FUSE mount helpers here.
  RegisterHelper(std::make_unique<DrivefsHelper>(platform(), process_reaper()));
  RegisterHelper(std::make_unique<FuseBoxHelper>(platform(), process_reaper()));
  RegisterHelper(std::make_unique<SshfsHelper>(
      platform(), process_reaper(), base::FilePath(working_dirs_root_)));
  RegisterHelper(std::make_unique<SmbfsHelper>(platform(), process_reaper()));

  return true;
}

std::unique_ptr<MountPoint> FUSEMountManager::DoMount(
    const std::string& source,
    const std::string& fuse_type,
    const std::vector<std::string>& options,
    const base::FilePath& mount_path,
    MountErrorType* error) {
  CHECK(!mount_path.empty()) << "Invalid mount path argument";

  Uri uri = Uri::Parse(source);
  CHECK(uri.valid()) << "Source " << quote(source) << " is not a URI";

  base::FilePath dir_name;
  const Mounter* selected_helper = nullptr;
  for (const auto& helper : helpers_) {
    if (helper->CanMount(source, options, &dir_name)) {
      selected_helper = helper.get();
      break;
    }
  }

  if (!selected_helper) {
    LOG(ERROR) << "Cannot find FUSE module for " << redact(source)
               << " of type " << quote(fuse_type);
    *error = MOUNT_ERROR_UNKNOWN_FILESYSTEM;
    return nullptr;
  }

  std::unique_ptr<MountPoint> mountpoint =
      selected_helper->Mount(source, mount_path, options, error);
  LOG_IF(ERROR, *error != MOUNT_ERROR_NONE)
      << "Cannot mount " << redact(source) << " of type " << quote(fuse_type)
      << ": " << *error;

  return mountpoint;
}

bool FUSEMountManager::CanMount(const std::string& source) const {
  base::FilePath dir;
  for (const auto& helper : helpers_) {
    if (helper->CanMount(source, {}, &dir))
      return true;
  }
  return false;
}

std::string FUSEMountManager::SuggestMountPath(
    const std::string& source) const {
  Uri uri = Uri::Parse(source);
  if (!uri.valid()) {
    return "";
  }

  base::FilePath dir;
  for (const auto& helper : helpers_) {
    if (helper->CanMount(source, {}, &dir))
      return mount_root().Append(dir).value();
  }
  base::FilePath base_name = base::FilePath(source).BaseName();
  return mount_root().Append(base_name).value();
}

void FUSEMountManager::RegisterHelper(std::unique_ptr<Mounter> helper) {
  helpers_.push_back(std::move(helper));
}

}  // namespace cros_disks
