// Copyright (c) 2012 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.

#ifndef CROS_DISKS_DISK_MANAGER_H_
#define CROS_DISKS_DISK_MANAGER_H_

#include <libudev.h>

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/callback.h>
#include <base/macros.h>
#include <gtest/gtest_prod.h>

#include "cros-disks/device_ejector.h"
#include "cros-disks/device_event.h"
#include "cros-disks/device_event_source_interface.h"
#include "cros-disks/mount_manager.h"

namespace cros_disks {

class DeviceEjector;
class Disk;
class Filesystem;
class Mounter;
class Platform;

// The DiskManager is responsible for reading device state from udev.
// Said changes could be the result of a udev notification or a synchronous
// call to enumerate the relevant storage devices attached to the system.
//
// Sample Usage:
//
// Platform platform;
// DiskManager manager("/media/removable", &platform);
// manager.Initialize();
// manager.EnumerateDisks();
// select(manager.udev_monitor_fd())...
//
// This class is designed to run within a single-threaded GMainLoop application
// and should not be considered thread safe.
class DiskManager : public MountManager, public DeviceEventSourceInterface {
 public:
  DiskManager(const std::string& mount_root,
              Platform* platform,
              Metrics* metrics,
              DeviceEjector* device_ejector);
  ~DiskManager() override;

  // Initializes the disk manager and registers default filesystems.
  // Returns true on success.
  bool Initialize() override;

  // Stops a session. Returns true on success.
  bool StopSession() override;

  // Returns true if mounting |source_path| is supported.
  bool CanMount(const std::string& source_path) const override;

  // Returns the type of mount sources supported by the manager.
  MountSourceType GetMountSourceType() const override {
    return MOUNT_SOURCE_REMOVABLE_DEVICE;
  }

  // Unmounts all mounted paths.
  bool UnmountAll() override;

  // Lists the current block devices attached to the system.
  std::vector<Disk> EnumerateDisks() const;

  // Implements the DeviceEventSourceInterface interface to read the changes
  // from udev and converts the changes into device events. Returns false on
  // error or if not device event is available. Must be called to clear the fd.
  bool GetDeviceEvents(DeviceEventList* events) override;

  // Gets a Disk object that corresponds to a given device file.
  bool GetDiskByDevicePath(const std::string& device_path, Disk* disk) const;

  // Registers a set of default filesystems to the disk manager.
  void RegisterDefaultFilesystems();

  // Registers a filesystem to the disk manager.
  // Subsequent registrations of the same filesystem type are ignored.
  void RegisterFilesystem(const Filesystem& filesystem);

  // A file descriptor that can be select()ed or poll()ed for system changes.
  int udev_monitor_fd() const { return udev_monitor_fd_; }

 protected:
  // Mounts |source_path| to |mount_path| as |filesystem_type| with |options|.
  MountErrorType DoMount(const std::string& source_path,
                         const std::string& filesystem_type,
                         const std::vector<std::string>& options,
                         const std::string& mount_path,
                         MountOptions* applied_options) override;

  // Unmounts |path| with |options|.
  MountErrorType DoUnmount(const std::string& path,
                           const std::vector<std::string>& options) override;

  // Returns a suggested mount path for a source path.
  std::string SuggestMountPath(const std::string& source_path) const override;

  // Returns true to reserve a mount path on errors due to unknown or
  // unsupported filesystems.
  bool ShouldReserveMountPathOnError(MountErrorType error_type) const override;

 private:
  // Creates an appropriate mounter object for a given filesystem.
  std::unique_ptr<Mounter> CreateMounter(
      const Disk& disk,
      const Filesystem& filesystem,
      const std::string& target_path,
      const std::vector<std::string>& options) const;

  // Returns a Filesystem object if a given filesystem type is supported.
  // Otherwise, it returns NULL. This pointer is owned by the DiskManager.
  const Filesystem* GetFilesystem(const std::string& filesystem_type) const;

  // An EnumerateBlockDevices callback that emulates a block device event
  // defined by |action| on |device|. Always returns true to continue
  // enumeration in EnumerateBlockDevices.
  bool EmulateBlockDeviceEvent(const char* action, udev_device* device);

  // Enumerates the block devices on the system and invokes |callback| for each
  // device found during the enumeration. The ownership of |udev_device| is not
  // transferred to |callback|. The enumeration stops if |callback| returns
  // false.
  void EnumerateBlockDevices(
      const base::Callback<bool(udev_device* dev)>& callback) const;

  // Determines one or more device/disk events from a udev block device change.
  void ProcessBlockDeviceEvents(udev_device* device,
                                const char* action,
                                DeviceEventList* events);

  // Determines one or more device/disk events from a udev MMC or SCSI device
  // change.
  void ProcessMmcOrScsiDeviceEvents(udev_device* device,
                                    const char* action,
                                    DeviceEventList* events);

  // If |disk| should be ejected on unmount, add |mount_path| and the device
  // file of |disk| to |devices_to_eject_on_unmount_| and returns true. Returns
  // false otherwise.
  bool ScheduleEjectOnUnmount(const std::string& mount_path, const Disk& disk);

  // Ejects media from a device mounted at |mount_path|. Return true if the
  // eject process has started, or false if the |mount_path| is not in
  // |devices_to_eject_on_unmount_| or |eject_device_on_unmount_| is set to
  // false.
  bool EjectDeviceOfMountPath(const std::string& mount_path);

  // Device ejector for ejecting media from optical devices.
  DeviceEjector* device_ejector_;

  // The root udev object.
  mutable udev* udev_;

  // Provides access to udev changes as they occur.
  udev_monitor* udev_monitor_;

  // A file descriptor that indicates changes to the system.
  int udev_monitor_fd_;

  // Set to true if devices should be ejected upon unmount.
  bool eject_device_on_unmount_;

  // A set of device sysfs paths detected by the udev monitor.
  std::set<std::string> devices_detected_;

  // A mapping from a mount path to the corresponding device file that should
  // be ejected on unmount.
  std::map<std::string, std::string> devices_to_eject_on_unmount_;

  // A mapping from a sysfs path of a disk, detected by the udev monitor,
  // to a set of sysfs paths of the immediate children of the disk.
  std::map<std::string, std::set<std::string>> disks_detected_;

  // A set of supported filesystems indexed by filesystem type.
  std::map<std::string, Filesystem> filesystems_;

  FRIEND_TEST(DiskManagerTest, CreateExFATMounter);
  FRIEND_TEST(DiskManagerTest, CreateExternalMounter);
  FRIEND_TEST(DiskManagerTest, CreateNTFSMounter);
  FRIEND_TEST(DiskManagerTest, CreateSystemMounter);
  FRIEND_TEST(DiskManagerTest, GetFilesystem);
  FRIEND_TEST(DiskManagerTest, RegisterFilesystem);
  FRIEND_TEST(DiskManagerTest, DoMountDiskWithNonexistentSourcePath);
  FRIEND_TEST(DiskManagerTest, DoUnmountDiskWithInvalidUnmountOptions);
  FRIEND_TEST(DiskManagerTest, ScheduleEjectOnUnmount);
  FRIEND_TEST(DiskManagerTest, EjectDeviceOfMountPath);
  FRIEND_TEST(DiskManagerTest, EjectDeviceOfMountPathWhenEjectFailed);
  FRIEND_TEST(DiskManagerTest, EjectDeviceOfMountPathWhenExplicitlyDisabled);
  FRIEND_TEST(DiskManagerTest, EjectDeviceOfMountPathWhenMountPathExcluded);

  DISALLOW_COPY_AND_ASSIGN(DiskManager);
};

}  // namespace cros_disks

#endif  // CROS_DISKS_DISK_MANAGER_H_
