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

#ifndef CHROMEOS_DISKS_MOCK_DISK_MOUNT_MANAGER_H_
#define CHROMEOS_DISKS_MOCK_DISK_MOUNT_MANAGER_H_

#include <stdint.h>

#include <string>

#include "base/macros.h"
#include "base/observer_list.h"
#include "chromeos/dbus/cros_disks_client.h"
#include "chromeos/disks/disk_mount_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromeos {
namespace disks {

// TODO(tbarzic): Replace this mock with a fake implementation
// (http://crbug.com/355757)
class MockDiskMountManager : public DiskMountManager {
 public:
  MockDiskMountManager();
  virtual ~MockDiskMountManager();

  // DiskMountManager override.
  MOCK_METHOD0(Init, void(void));
  void AddObserver(DiskMountManager::Observer*) override;
  void RemoveObserver(DiskMountManager::Observer*) override;
  MOCK_CONST_METHOD0(disks, const DiskMountManager::DiskMap&(void));
  MOCK_CONST_METHOD1(FindDiskBySourcePath, const Disk*(const std::string&));
  MOCK_CONST_METHOD0(mount_points,
                     const DiskMountManager::MountPointMap&(void));
  MOCK_METHOD2(EnsureMountInfoRefreshed,
               void(EnsureMountInfoRefreshedCallback, bool));
  MOCK_METHOD6(MountPath,
               void(const std::string&,
                    const std::string&,
                    const std::string&,
                    const std::vector<std::string>&,
                    MountType,
                    MountAccessMode));
  MOCK_METHOD3(UnmountPath,
               void(const std::string&,
                    UnmountOptions,
                    DiskMountManager::UnmountPathCallback));
  MOCK_METHOD1(RemountAllRemovableDrives, void(MountAccessMode));
  MOCK_METHOD1(FormatMountedDevice, void(const std::string&));
  MOCK_METHOD2(RenameMountedDevice,
               void(const std::string&, const std::string&));
  MOCK_METHOD2(UnmountDeviceRecursively,
               void(const std::string&,
                    DiskMountManager::UnmountDeviceRecursivelyCallbackType));

  // Invokes fake device insert events.
  void NotifyDeviceInsertEvents();

  // Invokes fake device remove events.
  void NotifyDeviceRemoveEvents();

  // Invokes specified mount event.
  void NotifyMountEvent(MountEvent event,
                        MountError error_code,
                        const MountPointInfo& mount_info);

  // Sets up default results for mock methods.
  void SetupDefaultReplies();

  // Creates a fake disk entry for the mounted device. This function is
  // primarily for StorageMonitorTest.
  void CreateDiskEntryForMountDevice(
      const DiskMountManager::MountPointInfo& mount_info,
      const std::string& device_id,
      const std::string& device_label,
      const std::string& vendor_name,
      const std::string& product_name,
      DeviceType device_type,
      uint64_t total_size_in_bytes,
      bool is_parent,
      bool has_media,
      bool on_boot_device,
      bool on_removable_device,
      const std::string& file_system_type);

  // Removes the fake disk entry associated with the mounted device. This
  // function is primarily for StorageMonitorTest.
  void RemoveDiskEntryForMountDevice(
      const DiskMountManager::MountPointInfo& mount_info);

 private:
  // Is used to implement AddObserver.
  void AddObserverInternal(DiskMountManager::Observer* observer);

  // Is used to implement RemoveObserver.
  void RemoveObserverInternal(DiskMountManager::Observer* observer);

  // Is used to implement disks.
  const DiskMountManager::DiskMap& disksInternal() const { return disks_; }

  const DiskMountManager::MountPointMap& mountPointsInternal() const;

  // Returns Disk object associated with the |source_path| or NULL on failure.
  const Disk* FindDiskBySourcePathInternal(
      const std::string& source_path) const;

  // Notifies observers about device status update.
  void NotifyDeviceChanged(DeviceEvent event,
                           const std::string& path);

  // Notifies observers about disk status update.
  void NotifyDiskChanged(DiskEvent event, const Disk* disk);

  // The list of observers.
  base::ObserverList<DiskMountManager::Observer>::Unchecked observers_;

  // The list of disks found.
  DiskMountManager::DiskMap disks_;

  // The list of existing mount points.
  DiskMountManager::MountPointMap mount_points_;

  DISALLOW_COPY_AND_ASSIGN(MockDiskMountManager);
};

}  // namespace disks
}  // namespace chromeos

#endif  // CHROMEOS_DISKS_MOCK_DISK_MOUNT_MANAGER_H_
