// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// TestVolumeMountWatcherWin implementation.

#include "components/storage_monitor/test_volume_mount_watcher_win.h"

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/utf_string_conversions.h"
#include "components/storage_monitor/storage_info.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace storage_monitor {

namespace {

base::FilePath GetTempRoot() {
  base::ScopedTempDir temp_dir;
  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath temp_root = temp_dir.GetPath();
  while (temp_root.DirName() != temp_root)
    temp_root = temp_root.DirName();
  return temp_root;
}

std::vector<base::FilePath> FakeGetSingleAttachedDevice() {
  std::vector<base::FilePath> result;
  result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(2));  // C

  // Make sure we are adding the drive on which ScopedTempDir will make
  // test directories.
  base::FilePath temp_root = GetTempRoot();
  if (temp_root != VolumeMountWatcherWin::DriveNumberToFilePath(2))
    result.push_back(temp_root);

  return result;
}

std::vector<base::FilePath> FakeGetAttachedDevices() {
  std::vector<base::FilePath> result;
  result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(0));  // A
  result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(1));  // B
  result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(2));  // C
  result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(3));  // D
  result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(5));  // F
  result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(7));  // H
  result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(13));  // N
  result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(25));  // Z
  return result;
}

// Gets the details of the mass storage device specified by the |device_path|.
// |device_path| inputs of 'A:\' - 'Z:\' are valid. 'N:\' is not removable.
// 'C:\' is not removable (so that auto-added paths are correctly handled).
bool GetMassStorageDeviceDetails(const base::FilePath& device_path,
                                 StorageInfo* info) {
  DCHECK(info);

  // Truncate to root path.
  base::FilePath path(device_path);
  if (device_path.value().length() > 3)
    path = base::FilePath(device_path.value().substr(0, 3));
  base::FilePath::CharType drive_letter = path.value()[0];
  if (drive_letter < L'A' || drive_letter > L'Z')
    return false;

  StorageInfo::Type type = StorageInfo::FIXED_MASS_STORAGE;
  if (path.value() != base::ASCIIToUTF16("N:\\") &&
      path.value() != base::ASCIIToUTF16("C:\\") &&
      path.value() != GetTempRoot().value()) {
    type = StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM;
  }
  std::string unique_id =
      "\\\\?\\Volume{00000000-0000-0000-0000-000000000000}\\";
  unique_id[11] = static_cast<char>(drive_letter);
  std::string device_id = StorageInfo::MakeDeviceId(type, unique_id);
  base::string16 storage_label = path.Append(L" Drive").LossyDisplayName();
  *info = StorageInfo(device_id, path.value(), storage_label, base::string16(),
                      base::string16(), 1000000);

  return true;
}

}  // namespace

// TestVolumeMountWatcherWin ---------------------------------------------------

TestVolumeMountWatcherWin::TestVolumeMountWatcherWin()
    : attached_devices_fake_(false) {}

TestVolumeMountWatcherWin::~TestVolumeMountWatcherWin() {
}

void TestVolumeMountWatcherWin::AddDeviceForTesting(
    const base::FilePath& device_path,
    const std::string& device_id,
    const base::string16& storage_label,
    uint64_t total_size_in_bytes) {
  StorageInfo info(device_id, device_path.value(), storage_label,
                   base::string16(), base::string16(), total_size_in_bytes);
  HandleDeviceAttachEventOnUIThread(device_path, info);
}

void TestVolumeMountWatcherWin::SetAttachedDevicesFake() {
  attached_devices_fake_ = true;
}

void TestVolumeMountWatcherWin::DeviceCheckComplete(
    const base::FilePath& device_path) {
  devices_checked_.push_back(device_path);
  if (device_check_complete_event_)
    device_check_complete_event_->Wait();
  VolumeMountWatcherWin::DeviceCheckComplete(device_path);
}

void TestVolumeMountWatcherWin::BlockDeviceCheckForTesting() {
  device_check_complete_event_.reset(
      new base::WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                              base::WaitableEvent::InitialState::NOT_SIGNALED));
  devices_checked_.clear();
}

void TestVolumeMountWatcherWin::ReleaseDeviceCheck() {
  device_check_complete_event_->Signal();
}

// static
bool TestVolumeMountWatcherWin::GetDeviceRemovable(
    const base::FilePath& device_path,
    bool* removable) {
  StorageInfo info;
  bool success = GetMassStorageDeviceDetails(device_path, &info);
  *removable = StorageInfo::IsRemovableDevice(info.device_id());
  return success;
}

VolumeMountWatcherWin::GetDeviceDetailsCallbackType
TestVolumeMountWatcherWin::GetDeviceDetailsCallback() const {
  return base::Bind(&GetMassStorageDeviceDetails);
}

VolumeMountWatcherWin::GetAttachedDevicesCallbackType
  TestVolumeMountWatcherWin::GetAttachedDevicesCallback() const {
  if (attached_devices_fake_)
    return base::Bind(&FakeGetAttachedDevices);
  return base::Bind(&FakeGetSingleAttachedDevice);
}

}  // namespace storage_monitor
