// Copyright (c) 2011 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/cros_disks_server.h"

#include <utility>

#include <base/check.h>
#include <base/logging.h>
#include <chromeos/dbus/service_constants.h>

#include "cros-disks/device_event.h"
#include "cros-disks/disk.h"
#include "cros-disks/disk_manager.h"
#include "cros-disks/disk_monitor.h"
#include "cros-disks/error_logger.h"
#include "cros-disks/format_manager.h"
#include "cros-disks/partition_manager.h"
#include "cros-disks/platform.h"
#include "cros-disks/quote.h"
#include "cros-disks/rename_manager.h"

namespace cros_disks {

CrosDisksServer::CrosDisksServer(scoped_refptr<dbus::Bus> bus,
                                 Platform* platform,
                                 DiskMonitor* disk_monitor,
                                 FormatManager* format_manager,
                                 PartitionManager* partition_manager,
                                 RenameManager* rename_manager)
    : org::chromium::CrosDisksAdaptor(this),
      dbus_object_(nullptr, bus, dbus::ObjectPath(kCrosDisksServicePath)),
      platform_(platform),
      disk_monitor_(disk_monitor),
      format_manager_(format_manager),
      partition_manager_(partition_manager),
      rename_manager_(rename_manager) {
  CHECK(platform_) << "Invalid platform object";
  CHECK(disk_monitor_) << "Invalid disk monitor object";
  CHECK(format_manager_) << "Invalid format manager object";
  CHECK(partition_manager_) << "Invalid partition manager object";
  CHECK(rename_manager_) << "Invalid rename manager object";

  format_manager_->set_observer(this);
  rename_manager_->set_observer(this);
}

void CrosDisksServer::RegisterAsync(
    const brillo::dbus_utils::AsyncEventSequencer::CompletionAction& cb) {
  RegisterWithDBusObject(&dbus_object_);
  dbus_object_.RegisterAsync(cb);
}

void CrosDisksServer::RegisterMountManager(MountManager* mount_manager) {
  CHECK(mount_manager) << "Invalid mount manager object";
  mount_managers_.push_back(mount_manager);
}

void CrosDisksServer::Format(const std::string& path,
                             const std::string& filesystem_type,
                             const std::vector<std::string>& options) {
  FormatErrorType error_type = FORMAT_ERROR_NONE;
  Disk disk;
  if (!disk_monitor_->GetDiskByDevicePath(base::FilePath(path), &disk)) {
    error_type = FORMAT_ERROR_INVALID_DEVICE_PATH;
  } else {
    error_type = format_manager_->StartFormatting(path, disk.device_file,
                                                  filesystem_type, options);
  }

  if (error_type != FORMAT_ERROR_NONE) {
    LOG(ERROR) << "Could not format device " << quote(path) << " as filesystem "
               << quote(filesystem_type) << ": " << error_type;
    SendFormatCompletedSignal(error_type, path);
  }
}

void CrosDisksServer::SinglePartitionFormat(
    std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<uint32_t>> response,
    const std::string& path) {
  Disk disk;

  if (!disk_monitor_->GetDiskByDevicePath(base::FilePath(path), &disk)) {
    LOG(ERROR) << "Invalid device path: " << quote(path)
               << " error code: " << PARTITION_ERROR_INVALID_DEVICE_PATH;
    response->Return(PARTITION_ERROR_INVALID_DEVICE_PATH);
  } else if (disk.is_on_boot_device || !disk.is_drive || disk.is_read_only) {
    LOG(ERROR) << "Device not allowed: " << quote(path)
               << " error code: " << PARTITION_ERROR_DEVICE_NOT_ALLOWED;
    response->Return(PARTITION_ERROR_DEVICE_NOT_ALLOWED);
  } else {
    partition_manager_->StartSinglePartitionFormat(
        base::FilePath(disk.device_file),
        base::BindOnce(&CrosDisksServer::OnPartitionCompleted,
                       base::Unretained(this), std::move(response)));
  }
}

void CrosDisksServer::Rename(const std::string& path,
                             const std::string& volume_name) {
  RenameErrorType error_type = RENAME_ERROR_NONE;
  Disk disk;
  if (!disk_monitor_->GetDiskByDevicePath(base::FilePath(path), &disk)) {
    error_type = RENAME_ERROR_INVALID_DEVICE_PATH;
  } else {
    error_type = rename_manager_->StartRenaming(
        path, disk.device_file, volume_name, disk.filesystem_type);
  }

  if (error_type != RENAME_ERROR_NONE) {
    LOG(ERROR) << "Could not rename device " << quote(path) << " as "
               << quote(volume_name) << ": " << error_type;
    SendRenameCompletedSignal(error_type, path);
  }
}

MountManager* CrosDisksServer::FindMounter(
    const std::string& source_path) const {
  for (const auto& manager : mount_managers_) {
    if (manager->CanMount(source_path)) {
      return manager;
    }
  }
  return nullptr;
}

void CrosDisksServer::Mount(const std::string& source,
                            const std::string& filesystem_type,
                            const std::vector<std::string>& options) {
  MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
  MountSourceType source_type = MOUNT_SOURCE_INVALID;
  std::string mount_path;

  MountManager* mounter = FindMounter(source);
  if (mounter) {
    source_type = mounter->GetMountSourceType();
    error_type = mounter->Mount(source, filesystem_type, options, &mount_path);
  }

  if (error_type != MOUNT_ERROR_NONE) {
    LOG(ERROR) << "Cannot mount " << redact(source) << " of type "
               << quote(filesystem_type) << ": " << error_type;
  }
  SendMountCompletedSignal(error_type, source, source_type, mount_path);
}

uint32_t CrosDisksServer::Unmount(const std::string& path,
                                  const std::vector<std::string>& options) {
  if (path.empty()) {
    LOG(ERROR) << "Cannot unmount an empty path";
    return MOUNT_ERROR_INVALID_ARGUMENT;
  }

  LOG_IF(WARNING, !options.empty())
      << "Ignoring non-empty unmount options " << quote(options);

  MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
  for (const auto& manager : mount_managers_) {
    error_type = manager->Unmount(path);
    if (error_type != MOUNT_ERROR_PATH_NOT_MOUNTED)
      break;
  }

  LOG_IF(ERROR, error_type != MOUNT_ERROR_NONE)
      << "Cannot unmount " << quote(path) << ": " << error_type;

  return error_type;
}

void CrosDisksServer::UnmountAll() {
  for (const auto& manager : mount_managers_) {
    manager->UnmountAll();
  }
}

std::vector<std::string> CrosDisksServer::EnumerateDevices() {
  std::vector<Disk> disks = disk_monitor_->EnumerateDisks();
  std::vector<std::string> devices;
  devices.reserve(disks.size());
  for (const auto& disk : disks) {
    devices.push_back(disk.native_path);
  }
  return devices;
}

std::vector<CrosDisksServer::DBusMountEntry>
CrosDisksServer::EnumerateMountEntries() {
  std::vector<DBusMountEntry> dbus_mount_entries;
  for (const auto& manager : mount_managers_) {
    for (const auto& mount_entry : manager->GetMountEntries()) {
      dbus_mount_entries.push_back(
          std::make_tuple(static_cast<uint32_t>(mount_entry.error_type),
                          mount_entry.source_path,
                          static_cast<uint32_t>(mount_entry.source_type),
                          mount_entry.mount_path));
    }
  }
  return dbus_mount_entries;
}

bool CrosDisksServer::GetDeviceProperties(
    brillo::ErrorPtr* error,
    const std::string& device_path,
    brillo::VariantDictionary* properties) {
  Disk disk;
  if (!disk_monitor_->GetDiskByDevicePath(base::FilePath(device_path), &disk)) {
    std::string message =
        "Could not get the properties of device " + device_path;
    LOG(ERROR) << message;
    brillo::Error::AddTo(error, FROM_HERE, brillo::errors::dbus::kDomain,
                         kCrosDisksServiceError, message);
    return false;
  }

  brillo::VariantDictionary temp_properties;
  temp_properties[kIsAutoMountable] = disk.is_auto_mountable;
  temp_properties[kDeviceIsDrive] = disk.is_drive;
  temp_properties[kDevicePresentationHide] = disk.is_hidden;
  temp_properties[kDeviceIsMounted] = disk.IsMounted();
  temp_properties[kDeviceIsMediaAvailable] = disk.is_media_available;
  temp_properties[kDeviceIsOnBootDevice] = disk.is_on_boot_device;
  temp_properties[kDeviceIsOnRemovableDevice] = disk.is_on_removable_device;
  temp_properties[kDeviceIsVirtual] = disk.is_virtual;
  temp_properties[kStorageDevicePath] = disk.storage_device_path;
  temp_properties[kDeviceFile] = disk.device_file;
  temp_properties[kIdUuid] = disk.uuid;
  temp_properties[kIdLabel] = disk.label;
  temp_properties[kVendorId] = disk.vendor_id;
  temp_properties[kVendorName] = disk.vendor_name;
  temp_properties[kProductId] = disk.product_id;
  temp_properties[kProductName] = disk.product_name;
  temp_properties[kDriveModel] = disk.drive_model;
  temp_properties[kDeviceMediaType] = static_cast<uint32_t>(disk.media_type);
  temp_properties[kBusNumber] = disk.bus_number;
  temp_properties[kDeviceNumber] = disk.device_number;
  temp_properties[kDeviceSize] = disk.device_capacity;
  temp_properties[kDeviceIsReadOnly] = disk.is_read_only;
  temp_properties[kFileSystemType] = disk.filesystem_type;
  temp_properties[kDeviceMountPaths] = disk.mount_paths;
  *properties = std::move(temp_properties);
  return true;
}

void CrosDisksServer::AddDeviceToAllowlist(const std::string& device_path) {
  disk_monitor_->AddDeviceToAllowlist(base::FilePath(device_path));
}

void CrosDisksServer::RemoveDeviceFromAllowlist(
    const std::string& device_path) {
  disk_monitor_->RemoveDeviceFromAllowlist(base::FilePath(device_path));
}

void CrosDisksServer::OnFormatCompleted(const std::string& device_path,
                                        FormatErrorType error_type) {
  SendFormatCompletedSignal(error_type, device_path);
}

void CrosDisksServer::OnPartitionCompleted(
    std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<uint32_t>> response,
    const base::FilePath& device_path,
    PartitionErrorType error_type) {
  LOG(ERROR) << "Partitioning for device " << quote(device_path)
             << " completed, result code: " << std::to_string(error_type);
  response->Return(error_type);
}

void CrosDisksServer::OnRenameCompleted(const std::string& device_path,
                                        RenameErrorType error_type) {
  SendRenameCompletedSignal(error_type, device_path);
}

void CrosDisksServer::OnScreenIsLocked() {
  // no-op
}

void CrosDisksServer::OnScreenIsUnlocked() {
  // no-op
}

void CrosDisksServer::OnSessionStarted() {
  for (const auto& manager : mount_managers_) {
    manager->StartSession();
  }
}

void CrosDisksServer::OnSessionStopped() {
  for (const auto& manager : mount_managers_) {
    manager->StopSession();
  }
}

void CrosDisksServer::DispatchDeviceEvent(const DeviceEvent& event) {
  switch (event.event_type) {
    case DeviceEvent::kDeviceAdded:
      SendDeviceAddedSignal(event.device_path);
      break;
    case DeviceEvent::kDeviceScanned:
      SendDeviceScannedSignal(event.device_path);
      break;
    case DeviceEvent::kDeviceRemoved:
      SendDeviceRemovedSignal(event.device_path);
      break;
    case DeviceEvent::kDiskAdded:
      SendDiskAddedSignal(event.device_path);
      break;
    case DeviceEvent::kDiskChanged:
      SendDiskChangedSignal(event.device_path);
      break;
    case DeviceEvent::kDiskRemoved:
      SendDiskRemovedSignal(event.device_path);
      break;
    default:
      break;
  }
}

}  // namespace cros_disks
