// 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.

#include "cros-disks/disk_manager.h"

#include <sys/mount.h>

#include <memory>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/stl_util.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "cros-disks/device_ejector.h"
#include "cros-disks/disk.h"
#include "cros-disks/exfat_mounter.h"
#include "cros-disks/external_mounter.h"
#include "cros-disks/filesystem.h"
#include "cros-disks/metrics.h"
#include "cros-disks/mounter.h"
#include "cros-disks/ntfs_mounter.h"
#include "cros-disks/platform.h"

using std::map;
using std::string;
using std::unique_ptr;
using std::vector;
using testing::Return;
using testing::_;

namespace {

const char kMountRootDirectory[] = "/media/removable";

}  // namespace

namespace cros_disks {

// A mock device ejector class for testing the disk manager class.
class MockDeviceEjector : public DeviceEjector {
 public:
  MockDeviceEjector() {}

  MOCK_METHOD1(Eject, bool(const string& device_path));
};

class DiskManagerTest : public ::testing::Test {
 public:
  DiskManagerTest()
      : manager_(kMountRootDirectory, &platform_, &metrics_, &device_ejector_) {
  }

 protected:
  Metrics metrics_;
  Platform platform_;
  MockDeviceEjector device_ejector_;
  DiskManager manager_;
};

TEST_F(DiskManagerTest, CreateExFATMounter) {
  Disk disk;
  disk.set_device_file("/dev/sda1");

  Filesystem filesystem("exfat");
  filesystem.set_mounter_type(ExFATMounter::kMounterType);

  string target_path = "/media/disk";
  vector<string> options = {"rw", "nodev", "noexec", "nosuid"};

  unique_ptr<Mounter> mounter(
      manager_.CreateMounter(disk, filesystem, target_path, options));
  EXPECT_NE(nullptr, mounter.get());
  EXPECT_EQ(filesystem.mount_type(), mounter->filesystem_type());
  EXPECT_EQ(disk.device_file(), mounter->source_path());
  EXPECT_EQ(target_path, mounter->target_path());
  EXPECT_EQ("rw,nodev,noexec,nosuid", mounter->mount_options().ToString());
}

TEST_F(DiskManagerTest, CreateExternalMounter) {
  Disk disk;
  disk.set_device_file("/dev/sda1");

  Filesystem filesystem("fat");
  filesystem.set_mount_type("vfat");
  filesystem.set_mounter_type(ExternalMounter::kMounterType);

  string target_path = "/media/disk";
  vector<string> options = {"rw", "nodev", "noexec", "nosuid"};

  unique_ptr<Mounter> mounter(
      manager_.CreateMounter(disk, filesystem, target_path, options));
  EXPECT_NE(nullptr, mounter.get());
  EXPECT_EQ(filesystem.mount_type(), mounter->filesystem_type());
  EXPECT_EQ(disk.device_file(), mounter->source_path());
  EXPECT_EQ(target_path, mounter->target_path());
  EXPECT_EQ("rw,nodev,noexec,nosuid", mounter->mount_options().ToString());
}

TEST_F(DiskManagerTest, CreateNTFSMounter) {
  Disk disk;
  disk.set_device_file("/dev/sda1");

  Filesystem filesystem("ntfs");
  filesystem.set_mounter_type(NTFSMounter::kMounterType);

  string target_path = "/media/disk";
  vector<string> options = {"rw", "nodev", "noexec", "nosuid"};

  unique_ptr<Mounter> mounter(
      manager_.CreateMounter(disk, filesystem, target_path, options));
  EXPECT_NE(nullptr, mounter.get());
  EXPECT_EQ(filesystem.mount_type(), mounter->filesystem_type());
  EXPECT_EQ(disk.device_file(), mounter->source_path());
  EXPECT_EQ(target_path, mounter->target_path());
  EXPECT_EQ("rw,nodev,noexec,nosuid", mounter->mount_options().ToString());
}

TEST_F(DiskManagerTest, CreateSystemMounter) {
  Disk disk;
  disk.set_device_file("/dev/sda1");

  Filesystem filesystem("vfat");
  filesystem.AddExtraMountOption("utf8");
  filesystem.AddExtraMountOption("shortname=mixed");

  string target_path = "/media/disk";
  vector<string> options = {"rw", "nodev", "noexec", "nosuid"};

  unique_ptr<Mounter> mounter(
      manager_.CreateMounter(disk, filesystem, target_path, options));
  EXPECT_NE(nullptr, mounter.get());
  EXPECT_EQ(filesystem.mount_type(), mounter->filesystem_type());
  EXPECT_EQ(disk.device_file(), mounter->source_path());
  EXPECT_EQ(target_path, mounter->target_path());
  EXPECT_EQ("utf8,shortname=mixed,rw,nodev,noexec,nosuid",
            mounter->mount_options().ToString());
}

TEST_F(DiskManagerTest, EnumerateDisks) {
  vector<Disk> disks = manager_.EnumerateDisks();
}

TEST_F(DiskManagerTest, GetDiskByDevicePath) {
  Disk disk;
  string device_path = "/dev/sda";
  EXPECT_TRUE(manager_.GetDiskByDevicePath(device_path, &disk));
  EXPECT_EQ(device_path, disk.device_file());

  device_path = "/dev/sda1";
  EXPECT_TRUE(manager_.GetDiskByDevicePath(device_path, &disk));
  EXPECT_EQ(device_path, disk.device_file());
}

TEST_F(DiskManagerTest, GetDiskByNonexistentDevicePath) {
  Disk disk;
  string device_path = "/dev/nonexistent-path";
  EXPECT_FALSE(manager_.GetDiskByDevicePath(device_path, &disk));
}

TEST_F(DiskManagerTest, GetFilesystem) {
  EXPECT_EQ(nullptr, manager_.GetFilesystem("nonexistent-fs"));

  Filesystem normal_fs("normal-fs");
  EXPECT_EQ(nullptr, manager_.GetFilesystem(normal_fs.type()));
  manager_.RegisterFilesystem(normal_fs);
  EXPECT_NE(nullptr, manager_.GetFilesystem(normal_fs.type()));
}

TEST_F(DiskManagerTest, RegisterFilesystem) {
  map<string, Filesystem>& filesystems = manager_.filesystems_;
  EXPECT_EQ(0, filesystems.size());
  EXPECT_TRUE(filesystems.find("nonexistent") == filesystems.end());

  Filesystem fat_fs("fat");
  fat_fs.set_accepts_user_and_group_id(true);
  manager_.RegisterFilesystem(fat_fs);
  EXPECT_EQ(1, filesystems.size());
  EXPECT_TRUE(filesystems.find(fat_fs.type()) != filesystems.end());

  Filesystem vfat_fs("vfat");
  vfat_fs.set_accepts_user_and_group_id(true);
  manager_.RegisterFilesystem(vfat_fs);
  EXPECT_EQ(2, filesystems.size());
  EXPECT_TRUE(filesystems.find(vfat_fs.type()) != filesystems.end());
}

TEST_F(DiskManagerTest, CanMount) {
  EXPECT_TRUE(manager_.CanMount("/dev/sda1"));
  EXPECT_TRUE(manager_.CanMount("/devices/block/sda/sda1"));
  EXPECT_TRUE(manager_.CanMount("/sys/devices/block/sda/sda1"));
  EXPECT_FALSE(manager_.CanMount("/media/removable/disk1"));
  EXPECT_FALSE(manager_.CanMount("/media/removable/disk1/"));
  EXPECT_FALSE(manager_.CanMount("/media/removable/disk 1"));
  EXPECT_FALSE(manager_.CanMount("/media/archive/test.zip"));
  EXPECT_FALSE(manager_.CanMount("/media/archive/test.zip/"));
  EXPECT_FALSE(manager_.CanMount("/media/archive/test 1.zip"));
  EXPECT_FALSE(manager_.CanMount("/media/removable/disk1/test.zip"));
  EXPECT_FALSE(manager_.CanMount("/media/removable/disk1/test 1.zip"));
  EXPECT_FALSE(manager_.CanMount("/media/removable/disk1/dir1/test.zip"));
  EXPECT_FALSE(manager_.CanMount("/media/removable/test.zip/test1.zip"));
  EXPECT_FALSE(manager_.CanMount("/home/chronos/user/Downloads/test1.zip"));
  EXPECT_FALSE(manager_.CanMount("/home/chronos/user/GCache/test1.zip"));
  EXPECT_FALSE(manager_.CanMount("/home/chronos"
                                 "/u-0123456789abcdef0123456789abcdef01234567"
                                 "/Downloads/test1.zip"));
  EXPECT_FALSE(manager_.CanMount("/home/chronos"
                                 "/u-0123456789abcdef0123456789abcdef01234567"
                                 "/GCache/test1.zip"));
  EXPECT_FALSE(manager_.CanMount(""));
  EXPECT_FALSE(manager_.CanMount("/tmp"));
  EXPECT_FALSE(manager_.CanMount("/media/removable"));
  EXPECT_FALSE(manager_.CanMount("/media/removable/"));
  EXPECT_FALSE(manager_.CanMount("/media/archive"));
  EXPECT_FALSE(manager_.CanMount("/media/archive/"));
  EXPECT_FALSE(manager_.CanMount("/home/chronos/user/Downloads"));
  EXPECT_FALSE(manager_.CanMount("/home/chronos/user/Downloads/"));
}

TEST_F(DiskManagerTest, CanUnmount) {
  EXPECT_TRUE(manager_.CanUnmount("/dev/sda1"));
  EXPECT_TRUE(manager_.CanUnmount("/devices/block/sda/sda1"));
  EXPECT_TRUE(manager_.CanUnmount("/sys/devices/block/sda/sda1"));
  EXPECT_TRUE(manager_.CanUnmount("/media/removable/disk1"));
  EXPECT_TRUE(manager_.CanUnmount("/media/removable/disk1/"));
  EXPECT_TRUE(manager_.CanUnmount("/media/removable/disk 1"));
  EXPECT_FALSE(manager_.CanUnmount("/media/archive/test.zip"));
  EXPECT_FALSE(manager_.CanUnmount("/media/archive/test.zip/"));
  EXPECT_FALSE(manager_.CanUnmount("/media/archive/test 1.zip"));
  EXPECT_FALSE(manager_.CanUnmount("/media/removable/disk1/test.zip"));
  EXPECT_FALSE(manager_.CanUnmount("/media/removable/disk1/test 1.zip"));
  EXPECT_FALSE(manager_.CanUnmount("/media/removable/disk1/dir1/test.zip"));
  EXPECT_FALSE(manager_.CanUnmount("/media/removable/test.zip/test1.zip"));
  EXPECT_FALSE(manager_.CanUnmount("/home/chronos/user/Downloads/test1.zip"));
  EXPECT_FALSE(manager_.CanUnmount("/home/chronos/user/GCache/test1.zip"));
  EXPECT_FALSE(manager_.CanUnmount("/home/chronos"
                                   "/u-0123456789abcdef0123456789abcdef01234567"
                                   "/Downloads/test1.zip"));
  EXPECT_FALSE(manager_.CanUnmount("/home/chronos"
                                   "/u-0123456789abcdef0123456789abcdef01234567"
                                   "/GCache/test1.zip"));
  EXPECT_FALSE(manager_.CanUnmount(""));
  EXPECT_FALSE(manager_.CanUnmount("/tmp"));
  EXPECT_FALSE(manager_.CanUnmount("/media/removable"));
  EXPECT_FALSE(manager_.CanUnmount("/media/removable/"));
  EXPECT_FALSE(manager_.CanUnmount("/media/archive"));
  EXPECT_FALSE(manager_.CanUnmount("/media/archive/"));
  EXPECT_FALSE(manager_.CanUnmount("/home/chronos/user/Downloads"));
  EXPECT_FALSE(manager_.CanUnmount("/home/chronos/user/Downloads/"));
}

TEST_F(DiskManagerTest, DoMountDiskWithNonexistentSourcePath) {
  string filesystem_type = "ext3";
  string source_path = "/dev/nonexistent-path";
  string mount_path = "/tmp/cros-disks-test";
  vector<string> options;
  EXPECT_EQ(MOUNT_ERROR_INVALID_DEVICE_PATH,
            manager_.DoMount(source_path, filesystem_type, options,
                             mount_path));
}

TEST_F(DiskManagerTest, DoUnmountDiskWithInvalidUnmountOptions) {
  string source_path = "/dev/nonexistent-path";
  vector<string> options = {"invalid-unmount-option"};
  EXPECT_EQ(MOUNT_ERROR_INVALID_UNMOUNT_OPTIONS,
            manager_.DoUnmount(source_path, options));
}

TEST_F(DiskManagerTest, ScheduleEjectOnUnmount) {
  string mount_path = "/media/removable/disk";
  Disk disk;
  disk.set_device_file("/dev/sr0");
  EXPECT_FALSE(manager_.ScheduleEjectOnUnmount(mount_path, disk));
  EXPECT_FALSE(ContainsKey(manager_.devices_to_eject_on_unmount_, mount_path));

  disk.set_media_type(DEVICE_MEDIA_OPTICAL_DISC);
  EXPECT_TRUE(manager_.ScheduleEjectOnUnmount(mount_path, disk));
  EXPECT_TRUE(ContainsKey(manager_.devices_to_eject_on_unmount_, mount_path));

  disk.set_media_type(DEVICE_MEDIA_DVD);
  manager_.devices_to_eject_on_unmount_.clear();
  EXPECT_TRUE(manager_.ScheduleEjectOnUnmount(mount_path, disk));
  EXPECT_TRUE(ContainsKey(manager_.devices_to_eject_on_unmount_, mount_path));
}

TEST_F(DiskManagerTest, EjectDeviceOfMountPath) {
  string mount_path = "/media/removable/disk";
  string device_file = "/dev/sr0";
  manager_.devices_to_eject_on_unmount_[mount_path] = device_file;
  EXPECT_CALL(device_ejector_, Eject(_)).WillOnce(Return(true));
  EXPECT_TRUE(manager_.EjectDeviceOfMountPath(mount_path));
  EXPECT_FALSE(ContainsKey(manager_.devices_to_eject_on_unmount_, mount_path));
}

TEST_F(DiskManagerTest, EjectDeviceOfMountPathWhenEjectFailed) {
  string mount_path = "/media/removable/disk";
  string device_file = "/dev/sr0";
  manager_.devices_to_eject_on_unmount_[mount_path] = device_file;
  EXPECT_CALL(device_ejector_, Eject(_)).WillOnce(Return(false));
  EXPECT_FALSE(manager_.EjectDeviceOfMountPath(mount_path));
  EXPECT_FALSE(ContainsKey(manager_.devices_to_eject_on_unmount_, mount_path));
}

TEST_F(DiskManagerTest, EjectDeviceOfMountPathWhenExplicitlyDisabled) {
  string mount_path = "/media/removable/disk";
  string device_file = "/dev/sr0";
  manager_.devices_to_eject_on_unmount_[mount_path] = device_file;
  manager_.eject_device_on_unmount_ = false;
  EXPECT_CALL(device_ejector_, Eject(_)).Times(0);
  EXPECT_FALSE(manager_.EjectDeviceOfMountPath(mount_path));
  EXPECT_FALSE(ContainsKey(manager_.devices_to_eject_on_unmount_, mount_path));
}

TEST_F(DiskManagerTest, EjectDeviceOfMountPathWhenMountPathExcluded) {
  EXPECT_CALL(device_ejector_, Eject(_)).Times(0);
  EXPECT_FALSE(manager_.EjectDeviceOfMountPath("/media/removable/disk"));
}

}  // namespace cros_disks
