// 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 "device/bluetooth/bluetooth_discovery_manager_mac.h"

#import <IOBluetooth/objc/IOBluetoothDevice.h>
#import <IOBluetooth/objc/IOBluetoothDeviceInquiry.h>

#include "base/mac/scoped_nsobject.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/logging.h"

namespace device {

class BluetoothDiscoveryManagerMacClassic;

}  // namespace device

// IOBluetoothDeviceInquiryDelegate implementation.
@interface BluetoothDeviceInquiryDelegate
    : NSObject<IOBluetoothDeviceInquiryDelegate> {
 @private
  device::BluetoothDiscoveryManagerMacClassic* manager_;  // weak
}

- (id)initWithManager:(device::BluetoothDiscoveryManagerMacClassic*)manager;

@end

namespace device {

// ementation of BluetoothDiscoveryManagerMac for Bluetooth classic device
// discovery, using the IOBluetooth framework.
class BluetoothDiscoveryManagerMacClassic
    : public BluetoothDiscoveryManagerMac {
 public:
  explicit BluetoothDiscoveryManagerMacClassic(Observer* observer)
      : BluetoothDiscoveryManagerMac(observer),
        should_do_discovery_(false),
        inquiry_running_(false),
        inquiry_delegate_(
            [[BluetoothDeviceInquiryDelegate alloc] initWithManager:this]),
        inquiry_([[IOBluetoothDeviceInquiry alloc]
            initWithDelegate:inquiry_delegate_]) {}

  virtual ~BluetoothDiscoveryManagerMacClassic() {}

  // BluetoothDiscoveryManagerMac override.
  virtual bool IsDiscovering() const OVERRIDE { return should_do_discovery_; }

  // BluetoothDiscoveryManagerMac override.
  virtual bool StartDiscovery() OVERRIDE {
    DVLOG(1) << "Bluetooth Classic: StartDiscovery";
    DCHECK(!should_do_discovery_);

    DVLOG(1) << "Discovery requested";
    should_do_discovery_ = true;

    if (inquiry_running_) {
      DVLOG(1) << "Device inquiry already running";
      return true;
    }

    DVLOG(1) << "Requesting to start device inquiry";
    if ([inquiry_ start] != kIOReturnSuccess) {
      DVLOG(1) << "Failed to start device inquiry";

      // Set |should_do_discovery_| to false here. Since we're reporting an
      // error, we're indicating that the adapter call StartDiscovery again
      // if needed.
      should_do_discovery_ = false;
      return false;
    }

    DVLOG(1) << "Device inquiry start was successful";
    return true;
  }

  // BluetoothDiscoveryManagerMac override.
  virtual bool StopDiscovery() OVERRIDE {
    DVLOG(1) << "Bluetooth Classic: StopDiscovery";
    DCHECK(should_do_discovery_);

    should_do_discovery_ = false;

    if (!inquiry_running_) {
      DVLOG(1) << "No device inquiry running; discovery stopped";
      return true;
    }

    DVLOG(1) << "Requesting to stop device inquiry";
    IOReturn status = [inquiry_ stop];
    if (status == kIOReturnSuccess) {
      DVLOG(1) << "Device inquiry stop was successful";
      return true;
    }

    if (status == kIOReturnNotPermitted) {
      DVLOG(1) << "Device inquiry was already stopped";
      return true;
    }

    LOG(WARNING) << "Failed to stop device inquiry";
    return false;
  }

  // Called by BluetoothDeviceInquiryDelegate.
  void DeviceInquiryStarted(IOBluetoothDeviceInquiry* inquiry) {
    DCHECK(!inquiry_running_);

    DVLOG(1) << "Device inquiry started!";

    // If discovery was requested to stop in the mean time, stop the inquiry.
    if (!should_do_discovery_) {
      DVLOG(1) << "Discovery stop was requested earlier. Stopping inquiry";
      [inquiry stop];
      return;
    }

    inquiry_running_ = true;
  }

  void DeviceFound(IOBluetoothDeviceInquiry* inquiry,
                   IOBluetoothDevice* device) {
    DCHECK(observer_);
    observer_->DeviceFound(this, device);
  }

  void DeviceInquiryComplete(IOBluetoothDeviceInquiry* inquiry,
                             IOReturn error,
                             bool aborted) {
    DCHECK_EQ(inquiry_, inquiry);
    DCHECK(observer_);
    DVLOG(1) << "Device inquiry complete";
    inquiry_running_ = false;

    // If discovery is no longer desired, notify observers that discovery
    // has stopped and return.
    if (!should_do_discovery_) {
      observer_->DiscoveryStopped(this, false /* unexpected */);
      return;
    }

    // If discovery has stopped due to an unexpected reason, notify the
    // observers and return.
    if (error != kIOReturnSuccess) {
      DVLOG(1) << "Inquiry has stopped with an error: " << error;
      should_do_discovery_ = false;
      observer_->DiscoveryStopped(this, true /* unexpected */);
      return;
    }

    DVLOG(1) << "Restarting device inquiry";

    if ([inquiry_ start] == kIOReturnSuccess) {
      DVLOG(1) << "Device inquiry restart was successful";
      return;
    }

    DVLOG(1) << "Failed to restart discovery";
    should_do_discovery_ = false;
    DCHECK(observer_);
    observer_->DiscoveryStopped(this, true /* unexpected */);
  }

 private:
  // The requested discovery state.
  bool should_do_discovery_;

  // The current inquiry state.
  bool inquiry_running_;

  // Objective-C objects for running and tracking device inquiry.
  base::scoped_nsobject<BluetoothDeviceInquiryDelegate> inquiry_delegate_;
  base::scoped_nsobject<IOBluetoothDeviceInquiry> inquiry_;

  DISALLOW_COPY_AND_ASSIGN(BluetoothDiscoveryManagerMacClassic);
};

BluetoothDiscoveryManagerMac::BluetoothDiscoveryManagerMac(
    Observer* observer) : observer_(observer) {
  DCHECK(observer);
}

BluetoothDiscoveryManagerMac::~BluetoothDiscoveryManagerMac() {
}

// static
BluetoothDiscoveryManagerMac* BluetoothDiscoveryManagerMac::CreateClassic(
    Observer* observer) {
  return new BluetoothDiscoveryManagerMacClassic(observer);
}

}  // namespace device

@implementation BluetoothDeviceInquiryDelegate

- (id)initWithManager:
          (device::BluetoothDiscoveryManagerMacClassic*)manager {
  if ((self = [super init]))
    manager_ = manager;

  return self;
}

- (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender {
  manager_->DeviceInquiryStarted(sender);
}

- (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender
                          device:(IOBluetoothDevice*)device {
  manager_->DeviceFound(sender, device);
}

- (void)deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender
                        error:(IOReturn)error
                      aborted:(BOOL)aborted {
  manager_->DeviceInquiryComplete(sender, error, aborted);
}

@end
