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

#include "components/storage_monitor/image_capture_device_manager.h"

#import <ImageCaptureCore/ImageCaptureCore.h>

#import "components/storage_monitor/image_capture_device.h"
#include "components/storage_monitor/storage_info.h"

namespace {

storage_monitor::ImageCaptureDeviceManager* g_image_capture_device_manager =
    NULL;

}  // namespace

// This class is the surface for the Mac ICDeviceBrowser ImageCaptureCore API.
// Owned by the ChromeBrowserParts and has browser process lifetime. Upon
// creation, it gets a list of attached media volumes (asynchronously) which
// it will eventually forward to StorageMonitor. It will also
// set up an ImageCaptureCore listener to be told when new devices/volumes
// are discovered and existing ones are removed.
@interface ImageCaptureDeviceManagerImpl
    : NSObject<ICDeviceBrowserDelegate> {
 @private
  base::scoped_nsobject<ICDeviceBrowser> _deviceBrowser;
  base::scoped_nsobject<NSMutableArray> _cameras;

  // Guaranteed to outlive this class.
  // TODO(gbillock): Update when ownership chains go up through
  // a StorageMonitor subclass.
  storage_monitor::StorageMonitor::Receiver* _notifications;
}

- (void)setNotifications:
        (storage_monitor::StorageMonitor::Receiver*)notifications;
- (void)close;

// The UUIDs passed here are available in the device attach notifications.
// They're gotten by cracking the device ID and taking the unique ID output.
- (ImageCaptureDevice*)deviceForUUID:(const std::string&)uuid;

- (ICDeviceBrowser*)deviceBrowserForTest;

@end

@implementation ImageCaptureDeviceManagerImpl

- (instancetype)init {
  if ((self = [super init])) {
    _cameras.reset([[NSMutableArray alloc] init]);
    _notifications = NULL;

    _deviceBrowser.reset([[ICDeviceBrowser alloc] init]);
    [_deviceBrowser setDelegate:self];
    [_deviceBrowser setBrowsedDeviceTypeMask:
        static_cast<ICDeviceTypeMask>(
            ICDeviceTypeMaskCamera | ICDeviceLocationTypeMaskLocal)];
    [_deviceBrowser start];
  }
  return self;
}

- (void)setNotifications:
            (storage_monitor::StorageMonitor::Receiver*)notifications {
  _notifications = notifications;
}

- (void)close {
  [_deviceBrowser setDelegate:nil];
  [_deviceBrowser stop];
  _deviceBrowser.reset();
  _cameras.reset();
}

- (ImageCaptureDevice*) deviceForUUID:(const std::string&)uuid {
  for (ICCameraDevice* camera in _cameras.get()) {
    NSString* camera_id = [camera UUIDString];
    if (base::SysNSStringToUTF8(camera_id) == uuid) {
      return [[[ImageCaptureDevice alloc]
          initWithCameraDevice:camera] autorelease];
    }
  }
  return nil;
}

- (void)deviceBrowser:(ICDeviceBrowser*)browser
         didAddDevice:(ICDevice*)addedDevice
           moreComing:(BOOL)moreComing {
  if (!(addedDevice.type & ICDeviceTypeCamera))
    return;

  // Ignore mass storage attaches -- those will be handled
  // by Mac's removable storage watcher.
  if ([addedDevice.transportType isEqualToString:ICTransportTypeMassStorage])
    return;

  ICCameraDevice* cameraDevice =
      base::mac::ObjCCastStrict<ICCameraDevice>(addedDevice);

  [_cameras addObject:addedDevice];

  // TODO(gbillock): use [cameraDevice mountPoint] here when possible.
  storage_monitor::StorageInfo info(
      storage_monitor::StorageInfo::MakeDeviceId(
          storage_monitor::StorageInfo::MAC_IMAGE_CAPTURE,
          base::SysNSStringToUTF8([cameraDevice UUIDString])),
      std::string(),
      base::SysNSStringToUTF16([cameraDevice name]),
      base::string16(),
      base::string16(),
      0);
  _notifications->ProcessAttach(info);
}

- (void)deviceBrowser:(ICDeviceBrowser*)browser
      didRemoveDevice:(ICDevice*)device
            moreGoing:(BOOL)moreGoing {
  if (!(device.type & ICDeviceTypeCamera))
    return;

  std::string uuid = base::SysNSStringToUTF8([device UUIDString]);

  // May delete |device|.
  [_cameras removeObject:device];

  _notifications->ProcessDetach(storage_monitor::StorageInfo::MakeDeviceId(
      storage_monitor::StorageInfo::MAC_IMAGE_CAPTURE, uuid));
}

- (ICDeviceBrowser*)deviceBrowserForTest {
  return _deviceBrowser.get();
}

@end  // ImageCaptureDeviceManagerImpl

namespace storage_monitor {

ImageCaptureDeviceManager::ImageCaptureDeviceManager() {
  device_browser_.reset([[ImageCaptureDeviceManagerImpl alloc] init]);
  g_image_capture_device_manager = this;
}

ImageCaptureDeviceManager::~ImageCaptureDeviceManager() {
  g_image_capture_device_manager = NULL;
  [device_browser_ close];
}

void ImageCaptureDeviceManager::SetNotifications(
    StorageMonitor::Receiver* notifications) {
  [device_browser_ setNotifications:notifications];
}

void ImageCaptureDeviceManager::EjectDevice(
    const std::string& uuid,
    base::OnceCallback<void(StorageMonitor::EjectStatus)> callback) {
  base::scoped_nsobject<ImageCaptureDevice> camera_device(
      [[device_browser_ deviceForUUID:uuid] retain]);
  [camera_device eject];
  [camera_device close];
  std::move(callback).Run(StorageMonitor::EJECT_OK);
}

// static
ImageCaptureDevice* ImageCaptureDeviceManager::deviceForUUID(
    const std::string& uuid) {
  ImageCaptureDeviceManagerImpl* manager =
      g_image_capture_device_manager->device_browser_;
  return [manager deviceForUUID:uuid];
}

id<ICDeviceBrowserDelegate>
ImageCaptureDeviceManager::device_browser_delegate() {
  return device_browser_.get();
}

ICDeviceBrowser* ImageCaptureDeviceManager::device_browser_for_test() {
  return [device_browser_ deviceBrowserForTest];
}

}  // namespace storage_monitor
