// Copyright 2013 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_adapter_mac.h"

#import <Foundation/Foundation.h>

#include <memory>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_path_watcher.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluetooth_discovery_session_outcome.h"
#import "device/bluetooth/bluetooth_low_energy_device_mac.h"
#include "device/bluetooth/bluetooth_low_energy_device_watcher_mac.h"
#import "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h"
#import "device/bluetooth/test/mock_bluetooth_central_manager_mac.h"
#import "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "third_party/ocmock/OCMock/OCMock.h"

#if defined(OS_IOS)
#import <CoreBluetooth/CoreBluetooth.h>
#else  // !defined(OS_IOS)
#import <IOBluetooth/IOBluetooth.h>
#endif  // defined(OS_IOS)

// List of undocumented IOBluetooth APIs used for BluetoothAdapterMac.
extern "C" {
int IOBluetoothPreferenceGetControllerPowerState();
void IOBluetoothPreferenceSetControllerPowerState(int state);
}

namespace {

const char kTestPropertyListFileName[] = "test_property_list_file.plist";

// |kTestHashAddress| is the hash corresponding to identifier |kTestNSUUID|.
const char kTestNSUUID[] = "00000000-1111-2222-3333-444444444444";
const char kTestHashAddress[] = "D1:6F:E3:22:FD:5B";
const int kTestRssi = 0;

NSDictionary* CreateTestPropertyListData() {
  return @{
    @"CoreBluetoothCache" : @{
      @"00000000-1111-2222-3333-444444444444" : @{
        @"DeviceAddress" : @"22-22-22-22-22-22",
        @"DeviceAddressType" : @1,
        @"ServiceChangedHandle" : @3,
        @"ServiceChangeSubscribed" : @0,
        @"ServiceDiscoveryComplete" : @0
      }
    }
  };
}

bool IsTestDeviceSystemPaired(const std::string& address) {
  return true;
}

}  // namespace

namespace device {

class BluetoothAdapterMacTest : public testing::Test {
 public:
  class FakeBluetoothLowEnergyDeviceWatcherMac
      : public BluetoothLowEnergyDeviceWatcherMac {
   public:
    FakeBluetoothLowEnergyDeviceWatcherMac(
        scoped_refptr<base::SequencedTaskRunner> ui_thread_task_runner,
        LowEnergyDeviceListUpdatedCallback callback)
        : BluetoothLowEnergyDeviceWatcherMac(ui_thread_task_runner, callback),
          weak_ptr_factory_(this) {}

    void SimulatePropertyListFileChanged(
        const base::FilePath& path,
        const std::string& changed_file_content) {
      auto expected_file_size = changed_file_content.length();
      ASSERT_EQ(static_cast<int>(expected_file_size),
                base::WriteFile(path, changed_file_content.data(),
                                expected_file_size));
      OnPropertyListFileChangedOnFileThread(path, false /* error */);
    }

   private:
    ~FakeBluetoothLowEnergyDeviceWatcherMac() override = default;

    void Init() override { ReadBluetoothPropertyListFile(); }

    void ReadBluetoothPropertyListFile() override {
      low_energy_device_list_updated_callback().Run(
          ParseBluetoothDevicePropertyListData(CreateTestPropertyListData()));
    }

    base::WeakPtrFactory<FakeBluetoothLowEnergyDeviceWatcherMac>
        weak_ptr_factory_;
  };

  BluetoothAdapterMacTest()
      : ui_task_runner_(new base::TestSimpleTaskRunner()),
        adapter_(new BluetoothAdapterMac()),
        adapter_mac_(static_cast<BluetoothAdapterMac*>(adapter_.get())),
        observer_(adapter_),
        callback_count_(0),
        error_callback_count_(0) {
    adapter_mac_->SetGetDevicePairedStatusCallbackForTesting(
        base::BindRepeating(&IsTestDeviceSystemPaired));
    adapter_mac_->InitForTest(ui_task_runner_);
    fake_low_energy_device_watcher_ =
        base::MakeRefCounted<FakeBluetoothLowEnergyDeviceWatcherMac>(
            ui_task_runner_,
            base::BindRepeating(
                &BluetoothAdapterMac::UpdateKnownLowEnergyDevices,
                adapter_mac_->weak_ptr_factory_.GetWeakPtr()));
  }

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    test_property_list_file_path_ =
        temp_dir_.GetPath().AppendASCII(kTestPropertyListFileName);
  }

  void TearDown() override { scoped_task_environment_.RunUntilIdle(); }

  // Helper methods for setup and access to BluetoothAdapterMacTest's members.
  void PollAdapter() { adapter_mac_->PollAdapter(); }

  void SetHostControllerPowerFunction(bool powered) {
    adapter_mac_->SetHostControllerStateFunctionForTesting(
        base::BindLambdaForTesting([powered] {
          BluetoothAdapterMac::HostControllerState state;
          state.classic_powered = powered;
          return state;
        }));
  }

  void LowEnergyDeviceUpdated(CBPeripheral* peripheral,
                              NSDictionary* advertisement_data,
                              int rssi) {
    adapter_mac_->LowEnergyDeviceUpdated(peripheral, advertisement_data, rssi);
  }

  BluetoothDevice* GetDevice(const std::string& address) {
    return adapter_->GetDevice(address);
  }

  CBPeripheral* CreateMockPeripheral(const char* identifier) {
    if (!BluetoothAdapterMac::IsLowEnergyAvailable()) {
      LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
      return nil;
    }
    base::scoped_nsobject<MockCBPeripheral> mock_peripheral(
        [[MockCBPeripheral alloc] initWithUTF8StringIdentifier:identifier]);
    return [[mock_peripheral peripheral] retain];
  }

  NSDictionary* AdvertisementData() {
    NSDictionary* advertisement_data = @{
      CBAdvertisementDataIsConnectable : @(YES),
      CBAdvertisementDataServiceDataKey : [NSDictionary dictionary],
    };
    return [advertisement_data retain];
  }

  std::string GetHashAddress(CBPeripheral* peripheral) {
    return BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
  }

  int NumDevices() { return adapter_mac_->devices_.size(); }

  bool DevicePresent(CBPeripheral* peripheral) {
    BluetoothDevice* device = adapter_mac_->GetDevice(
        BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral));
    return (device != NULL);
  }

  bool SetMockCentralManager(CBCentralManagerState desired_state) {
    if (!BluetoothAdapterMac::IsLowEnergyAvailable()) {
      LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
      return false;
    }
    mock_central_manager_.reset([[MockCentralManager alloc] init]);
    [mock_central_manager_ setState:desired_state];
    CBCentralManager* centralManager =
        static_cast<CBCentralManager*>(mock_central_manager_.get());
    adapter_mac_->SetCentralManagerForTesting(centralManager);
    return true;
  }

  void AddDiscoverySession(BluetoothDiscoveryFilter* discovery_filter) {
    adapter_mac_->AddDiscoverySession(
        discovery_filter,
        base::Bind(&BluetoothAdapterMacTest::Callback, base::Unretained(this)),
        base::Bind(&BluetoothAdapterMacTest::DiscoveryErrorCallback,
                   base::Unretained(this)));
  }

  void RemoveDiscoverySession(BluetoothDiscoveryFilter* discovery_filter) {
    adapter_mac_->RemoveDiscoverySession(
        discovery_filter,
        base::Bind(&BluetoothAdapterMacTest::Callback, base::Unretained(this)),
        base::Bind(&BluetoothAdapterMacTest::DiscoveryErrorCallback,
                   base::Unretained(this)));
  }

  int NumDiscoverySessions() { return adapter_mac_->num_discovery_sessions_; }

  void SetFakeLowEnergyDeviceWatcher() {
    adapter_mac_->SetLowEnergyDeviceWatcherForTesting(
        fake_low_energy_device_watcher_);
  }

  // Generic callbacks.
  void Callback() { ++callback_count_; }
  void ErrorCallback() { ++error_callback_count_; }
  void DiscoveryErrorCallback(UMABluetoothDiscoverySessionOutcome) {
    ++error_callback_count_;
  }

 protected:
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  scoped_refptr<base::TestSimpleTaskRunner> ui_task_runner_;
  scoped_refptr<BluetoothAdapter> adapter_;
  BluetoothAdapterMac* adapter_mac_;
  scoped_refptr<FakeBluetoothLowEnergyDeviceWatcherMac>
      fake_low_energy_device_watcher_;
  TestBluetoothAdapterObserver observer_;

  // Owned by |adapter_mac_|.
  base::scoped_nsobject<MockCentralManager> mock_central_manager_;

  int callback_count_;
  int error_callback_count_;
  base::ScopedTempDir temp_dir_;
  base::FilePath test_property_list_file_path_;
};

// Test if private IOBluetooth APIs are callable on all supported macOS
// versions.
TEST_F(BluetoothAdapterMacTest, IOBluetoothPrivateAPIs) {
  // Obtain current power state, toggle it, and reset it to it's original value.
  int previous_state = IOBluetoothPreferenceGetControllerPowerState();
  IOBluetoothPreferenceSetControllerPowerState(!previous_state);
  IOBluetoothPreferenceSetControllerPowerState(previous_state);
}

TEST_F(BluetoothAdapterMacTest, Poll) {
  PollAdapter();
  EXPECT_TRUE(ui_task_runner_->HasPendingTask());
}

TEST_F(BluetoothAdapterMacTest, PollAndChangePower) {
  // By default the adapter is powered off, check that this expectation matches
  // reality.
  EXPECT_FALSE(adapter_mac_->IsPowered());
  EXPECT_EQ(0, observer_.powered_changed_count());

  SetHostControllerPowerFunction(true);
  PollAdapter();
  EXPECT_TRUE(ui_task_runner_->HasPendingTask());
  ui_task_runner_->RunPendingTasks();
  EXPECT_EQ(1, observer_.powered_changed_count());
  EXPECT_TRUE(observer_.last_powered());
  EXPECT_TRUE(adapter_mac_->IsPowered());

  SetHostControllerPowerFunction(false);
  PollAdapter();
  EXPECT_TRUE(ui_task_runner_->HasPendingTask());
  ui_task_runner_->RunPendingTasks();
  EXPECT_EQ(2, observer_.powered_changed_count());
  EXPECT_FALSE(observer_.last_powered());
  EXPECT_FALSE(adapter_mac_->IsPowered());
}

TEST_F(BluetoothAdapterMacTest, AddDiscoverySessionWithLowEnergyFilter) {
  if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
    return;
  EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]);
  EXPECT_EQ(0, NumDiscoverySessions());

  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(
      new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE));
  AddDiscoverySession(discovery_filter.get());
  EXPECT_TRUE(ui_task_runner_->HasPendingTask());
  ui_task_runner_->RunPendingTasks();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(1, NumDiscoverySessions());

  // Check that adding a discovery session resulted in
  // scanForPeripheralsWithServices being called on the Central Manager.
  EXPECT_EQ(1, [mock_central_manager_ scanForPeripheralsCallCount]);
}

// TODO(krstnmnlsn): Test changing the filter when adding the second discovery
// session (once we have that ability).
TEST_F(BluetoothAdapterMacTest, AddSecondDiscoverySessionWithLowEnergyFilter) {
  if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
    return;
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(
      new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE));
  AddDiscoverySession(discovery_filter.get());
  EXPECT_TRUE(ui_task_runner_->HasPendingTask());
  ui_task_runner_->RunPendingTasks();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(1, NumDiscoverySessions());

  // We replaced the success callback handed to AddDiscoverySession, so
  // |adapter_mac_| should remain in a discovering state indefinitely.
  EXPECT_TRUE(adapter_mac_->IsDiscovering());

  AddDiscoverySession(discovery_filter.get());
  EXPECT_TRUE(ui_task_runner_->HasPendingTask());
  ui_task_runner_->RunPendingTasks();
  EXPECT_EQ(2, [mock_central_manager_ scanForPeripheralsCallCount]);
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(2, NumDiscoverySessions());
}

TEST_F(BluetoothAdapterMacTest, RemoveDiscoverySessionWithLowEnergyFilter) {
  if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
    return;
  EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]);

  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(
      new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE));
  AddDiscoverySession(discovery_filter.get());
  EXPECT_TRUE(ui_task_runner_->HasPendingTask());
  ui_task_runner_->RunPendingTasks();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(1, NumDiscoverySessions());

  EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]);
  RemoveDiscoverySession(discovery_filter.get());
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(0, NumDiscoverySessions());

  // Check that removing the discovery session resulted in stopScan being called
  // on the Central Manager.
  EXPECT_EQ(1, [mock_central_manager_ stopScanCallCount]);
}

TEST_F(BluetoothAdapterMacTest, RemoveDiscoverySessionWithLowEnergyFilterFail) {
  if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
    return;
  EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]);
  EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]);
  EXPECT_EQ(0, NumDiscoverySessions());

  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(
      new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE));
  RemoveDiscoverySession(discovery_filter.get());
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(0, NumDiscoverySessions());

  // Check that stopScan was not called.
  EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]);
}

TEST_F(BluetoothAdapterMacTest, CheckGetPeripheralHashAddress) {
  if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
    return;
  base::scoped_nsobject<CBPeripheral> mock_peripheral(
      CreateMockPeripheral(kTestNSUUID));
  if (!mock_peripheral)
    return;
  EXPECT_EQ(kTestHashAddress, GetHashAddress(mock_peripheral));
}

TEST_F(BluetoothAdapterMacTest, LowEnergyDeviceUpdatedNewDevice) {
  if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
    return;
  base::scoped_nsobject<CBPeripheral> mock_peripheral(
      CreateMockPeripheral(kTestNSUUID));
  if (!mock_peripheral)
    return;
  base::scoped_nsobject<NSDictionary> advertisement_data(AdvertisementData());

  EXPECT_EQ(0, NumDevices());
  EXPECT_FALSE(DevicePresent(mock_peripheral));
  LowEnergyDeviceUpdated(mock_peripheral, advertisement_data, kTestRssi);
  EXPECT_EQ(1, NumDevices());
  EXPECT_TRUE(DevicePresent(mock_peripheral));
}

TEST_F(BluetoothAdapterMacTest, GetSystemPairedLowEnergyDevice) {
  SetFakeLowEnergyDeviceWatcher();
  ui_task_runner_->RunUntilIdle();
  EXPECT_TRUE(
      adapter_mac_->IsBluetoothLowEnergyDeviceSystemPaired(kTestNSUUID));
}

TEST_F(BluetoothAdapterMacTest, GetNewlyPairedLowEnergyDevice) {
  constexpr char kPropertyListFileContentWithAddedDevice[] =
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
      "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
      "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
      "<plist version=\"1.0\">"
      "<dict>"
      "   <key>CoreBluetoothCache</key>"
      "     <dict> "
      "      <key>E7F8589A-A7D9-4B94-9A08-D89076A159F4</key>"
      "      <dict> "
      "         <key>DeviceAddress</key>"
      "         <string>11-11-11-11-11-11</string>"
      "         <key>DeviceAddressType</key>"
      "         <integer>1</integer>"
      "         <key>ServiceChangedHandle</key>"
      "         <integer>3</integer>"
      "         <key>ServiceChangeSubscribed</key>"
      "         <integer>0</integer>"
      "         <key>ServiceDiscoveryComplete</key>"
      "         <integer>0</integer>"
      "      </dict>"
      "      <key>00000000-1111-2222-3333-444444444444</key>"
      "      <dict> "
      "         <key>DeviceAddress</key>"
      "         <string>22-22-22-22-22-22</string>"
      "         <key>DeviceAddressType</key>"
      "         <integer>1</integer>"
      "         <key>ServiceChangedHandle</key>"
      "         <integer>3</integer>"
      "         <key>ServiceChangeSubscribed</key>"
      "         <integer>0</integer>"
      "         <key>ServiceDiscoveryComplete</key>"
      "         <integer>0</integer>"
      "      </dict>"

      "     </dict>"
      "</dict>"
      "</plist>";

  const char kTestAddedDeviceNSUUID[] = "E7F8589A-A7D9-4B94-9A08-D89076A159F4";

  ASSERT_TRUE(SetMockCentralManager(CBCentralManagerStatePoweredOn));

  base::scoped_nsobject<CBPeripheral> mock_peripheral_one(
      CreateMockPeripheral(kTestNSUUID));
  ASSERT_TRUE(mock_peripheral_one);

  LowEnergyDeviceUpdated(
      mock_peripheral_one,
      base::scoped_nsobject<NSDictionary>(AdvertisementData()), kTestRssi);

  base::scoped_nsobject<CBPeripheral> mock_peripheral_two(
      CreateMockPeripheral(kTestAddedDeviceNSUUID));
  ASSERT_TRUE(mock_peripheral_two);

  LowEnergyDeviceUpdated(
      mock_peripheral_two,
      base::scoped_nsobject<NSDictionary>(AdvertisementData()), kTestRssi);
  observer_.Reset();

  // BluetoothAdapterMac only notifies observers of changed devices detected by
  // BluetoothLowEnergyDeviceWatcherMac if the device has been already known to
  // the system(i.e. the changed device is in BluetoothAdatper::devices_). As
  // so, add mock devices prior to setting BluetoothLowenergyDeviceWatcherMac.
  SetFakeLowEnergyDeviceWatcher();

  EXPECT_EQ(1, observer_.device_changed_count());
  observer_.Reset();

  fake_low_energy_device_watcher_->SimulatePropertyListFileChanged(
      test_property_list_file_path_, kPropertyListFileContentWithAddedDevice);
  ui_task_runner_->RunUntilIdle();
  EXPECT_EQ(1, observer_.device_changed_count());
  EXPECT_TRUE(adapter_mac_->IsBluetoothLowEnergyDeviceSystemPaired(
      kTestAddedDeviceNSUUID));
}

TEST_F(BluetoothAdapterMacTest, NotifyObserverWhenDeviceIsUnpaired) {
  constexpr char kPropertyListFileContentWithRemovedDevice[] =
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
      "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
      "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
      "<plist version=\"1.0\">"
      "<dict>"
      "   <key>CoreBluetoothCache</key>"
      "     <dict> "
      "     </dict>"
      "</dict>"
      "</plist>";

  if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
    return;

  base::scoped_nsobject<CBPeripheral> mock_peripheral(
      CreateMockPeripheral(kTestNSUUID));
  if (!mock_peripheral)
    return;

  LowEnergyDeviceUpdated(
      mock_peripheral, base::scoped_nsobject<NSDictionary>(AdvertisementData()),
      kTestRssi);
  observer_.Reset();

  SetFakeLowEnergyDeviceWatcher();
  EXPECT_EQ(1, observer_.device_changed_count());
  observer_.Reset();

  fake_low_energy_device_watcher_->SimulatePropertyListFileChanged(
      test_property_list_file_path_, kPropertyListFileContentWithRemovedDevice);
  ui_task_runner_->RunUntilIdle();
  EXPECT_EQ(1, observer_.device_changed_count());
  EXPECT_FALSE(
      adapter_mac_->IsBluetoothLowEnergyDeviceSystemPaired(kTestNSUUID));
}

}  // namespace device
