// Copyright 2018 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 "chromeos/services/secure_channel/ble_connection_manager_impl.h"

#include <memory>
#include <tuple>
#include <utility>

#include "base/bind.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "base/test/task_environment.h"
#include "chromeos/components/multidevice/remote_device_test_util.h"
#include "chromeos/services/secure_channel/authenticated_channel_impl.h"
#include "chromeos/services/secure_channel/ble_advertiser_impl.h"
#include "chromeos/services/secure_channel/ble_constants.h"
#include "chromeos/services/secure_channel/ble_initiator_failure_type.h"
#include "chromeos/services/secure_channel/ble_listener_failure_type.h"
#include "chromeos/services/secure_channel/ble_scanner_impl.h"
#include "chromeos/services/secure_channel/ble_synchronizer.h"
#include "chromeos/services/secure_channel/ble_weave_client_connection.h"
#include "chromeos/services/secure_channel/fake_authenticated_channel.h"
#include "chromeos/services/secure_channel/fake_ble_advertiser.h"
#include "chromeos/services/secure_channel/fake_ble_scanner.h"
#include "chromeos/services/secure_channel/fake_ble_service_data_helper.h"
#include "chromeos/services/secure_channel/fake_ble_synchronizer.h"
#include "chromeos/services/secure_channel/fake_connection.h"
#include "chromeos/services/secure_channel/fake_secure_channel_connection.h"
#include "chromeos/services/secure_channel/fake_secure_channel_disconnector.h"
#include "chromeos/services/secure_channel/fake_timer_factory.h"
#include "chromeos/services/secure_channel/secure_channel.h"
#include "chromeos/services/secure_channel/secure_channel_disconnector_impl.h"
#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromeos {

namespace secure_channel {

namespace {

const size_t kNumTestDevices = 5;

constexpr base::TimeDelta kScanToAdvertisementTime =
    base::TimeDelta::FromSeconds(3);
constexpr base::TimeDelta kAdvertisementToConnectionTime =
    base::TimeDelta::FromSeconds(2);
constexpr base::TimeDelta kConnectionToAuthenticationTime =
    base::TimeDelta::FromSeconds(1);

class FakeBleSynchronizerFactory : public BleSynchronizer::Factory {
 public:
  FakeBleSynchronizerFactory(
      scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
          expected_mock_adapter)
      : expected_mock_adapter_(expected_mock_adapter) {}

  ~FakeBleSynchronizerFactory() override = default;

  FakeBleSynchronizer* instance() { return instance_; }

 private:
  // BleSynchronizer::Factory:
  std::unique_ptr<BleSynchronizerBase> CreateInstance(
      scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) override {
    EXPECT_EQ(expected_mock_adapter_, bluetooth_adapter);
    EXPECT_FALSE(instance_);

    auto instance = std::make_unique<FakeBleSynchronizer>();
    instance_ = instance.get();
    return instance;
  }

  FakeBleSynchronizer* instance_ = nullptr;

  scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
      expected_mock_adapter_;

  DISALLOW_COPY_AND_ASSIGN(FakeBleSynchronizerFactory);
};

class FakeBleAdvertiserFactory : public BleAdvertiserImpl::Factory {
 public:
  FakeBleAdvertiserFactory(
      FakeBleServiceDataHelper* expected_fake_ble_service_data_helper,
      FakeBleSynchronizerFactory* fake_ble_synchronizer_factory,
      FakeTimerFactory* expected_fake_timer_factory)
      : expected_fake_ble_service_data_helper_(
            expected_fake_ble_service_data_helper),
        fake_ble_synchronizer_factory_(fake_ble_synchronizer_factory),
        expected_fake_timer_factory_(expected_fake_timer_factory) {}

  ~FakeBleAdvertiserFactory() override = default;

  FakeBleAdvertiser* instance() { return instance_; }

 private:
  // BleAdvertiserImpl::Factory:
  std::unique_ptr<BleAdvertiser> CreateInstance(
      BleAdvertiser::Delegate* delegate,
      BleServiceDataHelper* ble_service_data_helper,
      BleSynchronizerBase* ble_synchronizer_base,
      TimerFactory* timer_factory,
      scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner) override {
    EXPECT_EQ(expected_fake_ble_service_data_helper_, ble_service_data_helper);
    EXPECT_EQ(fake_ble_synchronizer_factory_->instance(),
              ble_synchronizer_base);
    EXPECT_EQ(expected_fake_timer_factory_, timer_factory);
    EXPECT_FALSE(instance_);

    auto instance = std::make_unique<FakeBleAdvertiser>(delegate);
    instance_ = instance.get();
    return instance;
  }

  FakeBleAdvertiser* instance_ = nullptr;

  FakeBleServiceDataHelper* expected_fake_ble_service_data_helper_;
  FakeBleSynchronizerFactory* fake_ble_synchronizer_factory_;
  FakeTimerFactory* expected_fake_timer_factory_;

  DISALLOW_COPY_AND_ASSIGN(FakeBleAdvertiserFactory);
};

class FakeBleScannerFactory : public BleScannerImpl::Factory {
 public:
  FakeBleScannerFactory(
      scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
          expected_mock_adapter,
      FakeBleServiceDataHelper* expected_fake_ble_service_data_helper,
      FakeBleSynchronizerFactory* fake_ble_synchronizer_factory)
      : expected_mock_adapter_(expected_mock_adapter),
        expected_fake_ble_service_data_helper_(
            expected_fake_ble_service_data_helper),
        fake_ble_synchronizer_factory_(fake_ble_synchronizer_factory) {}

  ~FakeBleScannerFactory() override = default;

  FakeBleScanner* instance() { return instance_; }

 private:
  // BleScannerImpl::Factory:
  std::unique_ptr<BleScanner> CreateInstance(
      BleScanner::Delegate* delegate,
      BleServiceDataHelper* service_data_helper,
      BleSynchronizerBase* ble_synchronizer_base,
      scoped_refptr<device::BluetoothAdapter> adapter) override {
    EXPECT_EQ(expected_fake_ble_service_data_helper_, service_data_helper);
    EXPECT_EQ(fake_ble_synchronizer_factory_->instance(),
              ble_synchronizer_base);
    EXPECT_EQ(expected_mock_adapter_, adapter);
    EXPECT_FALSE(instance_);

    auto instance = std::make_unique<FakeBleScanner>(delegate);
    instance_ = instance.get();
    return instance;
  }

  FakeBleScanner* instance_ = nullptr;

  scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
      expected_mock_adapter_;
  FakeBleServiceDataHelper* expected_fake_ble_service_data_helper_;
  FakeBleSynchronizerFactory* fake_ble_synchronizer_factory_;

  DISALLOW_COPY_AND_ASSIGN(FakeBleScannerFactory);
};

class FakeSecureChannelDisconnectorFactory
    : public SecureChannelDisconnectorImpl::Factory {
 public:
  FakeSecureChannelDisconnectorFactory() = default;
  ~FakeSecureChannelDisconnectorFactory() override = default;

  FakeSecureChannelDisconnector* instance() { return instance_; }

 private:
  // SecureChannelDisconnectorImpl::Factory:
  std::unique_ptr<SecureChannelDisconnector> CreateInstance() override {
    auto instance = std::make_unique<FakeSecureChannelDisconnector>();
    instance_ = instance.get();
    return instance;
  }

  FakeSecureChannelDisconnector* instance_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(FakeSecureChannelDisconnectorFactory);
};

class FakeWeaveClientConnectionFactory
    : public weave::BluetoothLowEnergyWeaveClientConnection::Factory {
 public:
  FakeWeaveClientConnectionFactory(
      scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
          expected_mock_adapter)
      : expected_mock_adapter_(expected_mock_adapter) {}

  virtual ~FakeWeaveClientConnectionFactory() = default;

  void set_expected_bluetooth_device(
      device::MockBluetoothDevice* expected_bluetooth_device) {
    expected_bluetooth_device_ = expected_bluetooth_device;
  }

  FakeConnection* last_created_instance() { return last_created_instance_; }

 private:
  // cryptauth::BluetoothLowEnergyWeaveClientConnection::Factory:
  std::unique_ptr<Connection> CreateInstance(
      multidevice::RemoteDeviceRef remote_device,
      scoped_refptr<device::BluetoothAdapter> adapter,
      const device::BluetoothUUID remote_service_uuid,
      const std::string& device_address,
      bool should_set_low_connection_latency) override {
    EXPECT_EQ(expected_mock_adapter_, adapter);
    EXPECT_EQ(device::BluetoothUUID(kGattServerUuid), remote_service_uuid);
    EXPECT_TRUE(should_set_low_connection_latency);

    auto instance = std::make_unique<FakeConnection>(remote_device);
    last_created_instance_ = instance.get();
    return instance;
  }

  scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
      expected_mock_adapter_;
  device::MockBluetoothDevice* expected_bluetooth_device_;

  FakeConnection* last_created_instance_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(FakeWeaveClientConnectionFactory);
};

class FakeSecureChannelFactory : public SecureChannel::Factory {
 public:
  FakeSecureChannelFactory(
      FakeWeaveClientConnectionFactory* fake_weave_client_connection_factory)
      : fake_weave_client_connection_factory_(
            fake_weave_client_connection_factory) {}

  virtual ~FakeSecureChannelFactory() = default;

  FakeSecureChannelConnection* last_created_instance() {
    return last_created_instance_;
  }

 private:
  // SecureChannel::Factory:
  std::unique_ptr<SecureChannel> CreateInstance(
      std::unique_ptr<Connection> connection) override {
    EXPECT_EQ(fake_weave_client_connection_factory_->last_created_instance(),
              connection.get());

    auto instance =
        std::make_unique<FakeSecureChannelConnection>(std::move(connection));
    last_created_instance_ = instance.get();
    return instance;
  }

  FakeWeaveClientConnectionFactory* fake_weave_client_connection_factory_;

  FakeSecureChannelConnection* last_created_instance_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(FakeSecureChannelFactory);
};

class FakeAuthenticatedChannelFactory
    : public AuthenticatedChannelImpl::Factory {
 public:
  FakeAuthenticatedChannelFactory() = default;
  ~FakeAuthenticatedChannelFactory() override = default;

  void SetExpectationsForNextCall(
      FakeSecureChannelConnection* expected_fake_secure_channel,
      bool expected_to_be_background_advertisement) {
    expected_fake_secure_channel_ = expected_fake_secure_channel;
    expected_to_be_background_advertisement_ =
        expected_to_be_background_advertisement;
  }

  FakeAuthenticatedChannel* last_created_instance() {
    return last_created_instance_;
  }

 private:
  // AuthenticatedChannelImpl::Factory:
  std::unique_ptr<AuthenticatedChannel> CreateInstance(
      const std::vector<mojom::ConnectionCreationDetail>&
          connection_creation_details,
      std::unique_ptr<SecureChannel> secure_channel) override {
    EXPECT_EQ(expected_fake_secure_channel_, secure_channel.get());
    EXPECT_EQ(1u, connection_creation_details.size());
    if (expected_to_be_background_advertisement_) {
      EXPECT_EQ(mojom::ConnectionCreationDetail::
                    REMOTE_DEVICE_USED_BACKGROUND_BLE_ADVERTISING,
                connection_creation_details[0]);
    } else {
      EXPECT_EQ(mojom::ConnectionCreationDetail::
                    REMOTE_DEVICE_USED_FOREGROUND_BLE_ADVERTISING,
                connection_creation_details[0]);
    }

    auto instance = std::make_unique<FakeAuthenticatedChannel>();
    last_created_instance_ = instance.get();
    return instance;
  }

  FakeSecureChannelConnection* expected_fake_secure_channel_ = nullptr;
  bool expected_to_be_background_advertisement_ = false;

  FakeAuthenticatedChannel* last_created_instance_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(FakeAuthenticatedChannelFactory);
};

}  // namespace

class SecureChannelBleConnectionManagerImplTest : public testing::Test {
 protected:
  SecureChannelBleConnectionManagerImplTest()
      : task_environment_(
            base::test::TaskEnvironment::MainThreadType::DEFAULT,
            base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED),
        test_devices_(
            multidevice::CreateRemoteDeviceRefListForTest(kNumTestDevices)) {}
  ~SecureChannelBleConnectionManagerImplTest() override = default;

  // testing::Test:
  void SetUp() override {
    mock_adapter_ =
        base::MakeRefCounted<testing::NiceMock<device::MockBluetoothAdapter>>();

    fake_ble_service_data_helper_ =
        std::make_unique<FakeBleServiceDataHelper>();

    fake_timer_factory_ = std::make_unique<FakeTimerFactory>();

    test_clock_ = std::make_unique<base::SimpleTestClock>();
    test_clock_->SetNow(base::Time::UnixEpoch());

    fake_ble_synchronizer_factory_ =
        std::make_unique<FakeBleSynchronizerFactory>(mock_adapter_);
    BleSynchronizer::Factory::SetFactoryForTesting(
        fake_ble_synchronizer_factory_.get());

    fake_ble_advertiser_factory_ = std::make_unique<FakeBleAdvertiserFactory>(
        fake_ble_service_data_helper_.get(),
        fake_ble_synchronizer_factory_.get(), fake_timer_factory_.get());
    BleAdvertiserImpl::Factory::SetFactoryForTesting(
        fake_ble_advertiser_factory_.get());

    fake_ble_scanner_factory_ = std::make_unique<FakeBleScannerFactory>(
        mock_adapter_, fake_ble_service_data_helper_.get(),
        fake_ble_synchronizer_factory_.get());
    BleScannerImpl::Factory::SetFactoryForTesting(
        fake_ble_scanner_factory_.get());

    fake_secure_channel_disconnector_factory_ =
        std::make_unique<FakeSecureChannelDisconnectorFactory>();
    SecureChannelDisconnectorImpl::Factory::SetFactoryForTesting(
        fake_secure_channel_disconnector_factory_.get());

    fake_weave_client_connection_factory_ =
        std::make_unique<FakeWeaveClientConnectionFactory>(mock_adapter_);
    weave::BluetoothLowEnergyWeaveClientConnection::Factory::
        SetFactoryForTesting(fake_weave_client_connection_factory_.get());

    fake_secure_channel_factory_ = std::make_unique<FakeSecureChannelFactory>(
        fake_weave_client_connection_factory_.get());
    SecureChannel::Factory::SetFactoryForTesting(
        fake_secure_channel_factory_.get());

    fake_authenticated_channel_factory_ =
        std::make_unique<FakeAuthenticatedChannelFactory>();
    AuthenticatedChannelImpl::Factory::SetFactoryForTesting(
        fake_authenticated_channel_factory_.get());

    manager_ = BleConnectionManagerImpl::Factory::Create(
        mock_adapter_, fake_ble_service_data_helper_.get(),
        fake_timer_factory_.get(), test_clock_.get());
  }

  void TearDown() override {
    BleSynchronizer::Factory::SetFactoryForTesting(nullptr);
    BleAdvertiserImpl::Factory::SetFactoryForTesting(nullptr);
    BleScannerImpl::Factory::SetFactoryForTesting(nullptr);
    SecureChannelDisconnectorImpl::Factory::SetFactoryForTesting(nullptr);
    weave::BluetoothLowEnergyWeaveClientConnection::Factory::
        SetFactoryForTesting(nullptr);
    SecureChannel::Factory::SetFactoryForTesting(nullptr);
    AuthenticatedChannelImpl::Factory::SetFactoryForTesting(nullptr);
  }

  void AttemptBleInitiatorConnection(const DeviceIdPair& device_id_pair,
                                     ConnectionPriority connection_priority,
                                     bool expected_to_add_request,
                                     bool should_cancel_attempt_on_failure) {
    SetInRemoteDeviceIdToMetadataMap(
        device_id_pair, ConnectionRole::kInitiatorRole, connection_priority);

    EXPECT_FALSE(fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));

    manager_->AttemptBleInitiatorConnection(
        device_id_pair, connection_priority,
        base::BindOnce(
            &SecureChannelBleConnectionManagerImplTest::OnConnectionSuccess,
            base::Unretained(this), device_id_pair,
            false /* created_via_background_advertisement */),
        base::BindRepeating(
            &SecureChannelBleConnectionManagerImplTest::OnBleInitiatorFailure,
            base::Unretained(this), device_id_pair,
            should_cancel_attempt_on_failure));

    if (expected_to_add_request) {
      EXPECT_EQ(connection_priority,
                *fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
      EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
          device_id_pair, ConnectionRole::kInitiatorRole)));
    } else {
      EXPECT_FALSE(
          fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
      EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
          device_id_pair, ConnectionRole::kInitiatorRole)));
    }
  }

  void UpdateBleInitiatorConnectionPriority(
      const DeviceIdPair& device_id_pair,
      ConnectionPriority connection_priority,
      bool expected_to_update_priority) {
    SetInRemoteDeviceIdToMetadataMap(
        device_id_pair, ConnectionRole::kInitiatorRole, connection_priority);

    manager_->UpdateBleInitiatorConnectionPriority(device_id_pair,
                                                   connection_priority);

    if (expected_to_update_priority) {
      EXPECT_EQ(connection_priority,
                *fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
      EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
          device_id_pair, ConnectionRole::kInitiatorRole)));
    } else {
      EXPECT_FALSE(
          fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
      EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
          device_id_pair, ConnectionRole::kInitiatorRole)));
    }
  }

  void CancelBleInitiatorConnectionAttempt(const DeviceIdPair& device_id_pair) {
    RemoveFromRemoteDeviceIdToMetadataMap(device_id_pair,
                                          ConnectionRole::kInitiatorRole);
    manager_->CancelBleInitiatorConnectionAttempt(device_id_pair);
    EXPECT_FALSE(fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
    EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
        device_id_pair, ConnectionRole::kInitiatorRole)));
  }

  void AttemptBleListenerConnection(const DeviceIdPair& device_id_pair,
                                    ConnectionPriority connection_priority,
                                    bool expected_to_add_request,
                                    bool should_cancel_attempt_on_failure) {
    SetInRemoteDeviceIdToMetadataMap(
        device_id_pair, ConnectionRole::kListenerRole, connection_priority);

    manager_->AttemptBleListenerConnection(
        device_id_pair, connection_priority,
        base::BindOnce(
            &SecureChannelBleConnectionManagerImplTest::OnConnectionSuccess,
            base::Unretained(this), device_id_pair,
            true /* created_via_background_advertisement */),
        base::BindRepeating(
            &SecureChannelBleConnectionManagerImplTest::OnBleListenerFailure,
            base::Unretained(this), device_id_pair,
            should_cancel_attempt_on_failure));

    if (expected_to_add_request) {
      EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
          device_id_pair, ConnectionRole::kListenerRole)));
    } else {
      EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
          device_id_pair, ConnectionRole::kListenerRole)));
    }
  }

  void UpdateBleListenerConnectionPriority(
      const DeviceIdPair& device_id_pair,
      ConnectionPriority connection_priority,
      bool expected_to_update_priority) {
    SetInRemoteDeviceIdToMetadataMap(
        device_id_pair, ConnectionRole::kListenerRole, connection_priority);

    manager_->UpdateBleListenerConnectionPriority(device_id_pair,
                                                  connection_priority);

    if (expected_to_update_priority) {
      EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
          device_id_pair, ConnectionRole::kListenerRole)));
    } else {
      EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
          device_id_pair, ConnectionRole::kListenerRole)));
    }
  }

  void CancelBleListenerConnectionAttempt(const DeviceIdPair& device_id_pair) {
    RemoveFromRemoteDeviceIdToMetadataMap(device_id_pair,
                                          ConnectionRole::kListenerRole);
    manager_->CancelBleListenerConnectionAttempt(device_id_pair);
    EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(
        BleScanner::ScanFilter(device_id_pair, ConnectionRole::kListenerRole)));
  }

  void SimulateBleSlotEnding(const DeviceIdPair& device_id_pair,
                             bool replaced_by_higher_priority_advertisement) {
    size_t num_failures_before_call = ble_initiator_failures_.size();

    fake_ble_advertiser()->NotifyAdvertisingSlotEnded(
        device_id_pair, replaced_by_higher_priority_advertisement);
    EXPECT_EQ(num_failures_before_call + 1u, ble_initiator_failures_.size());
    EXPECT_EQ(device_id_pair, ble_initiator_failures_.back().first);
    EXPECT_EQ(replaced_by_higher_priority_advertisement
                  ? BleInitiatorFailureType::
                        kInterruptedByHigherPriorityConnectionAttempt
                  : BleInitiatorFailureType::kTimeoutContactingRemoteDevice,
              ble_initiator_failures_.back().second);
  }

  void SimulateBleFailureToGenerateAdvertisement(
      const DeviceIdPair& device_id_pair) {
    size_t num_failures_before_call = ble_initiator_failures_.size();

    fake_ble_advertiser()->NotifyFailureToGenerateAdvertisement(device_id_pair);
    EXPECT_EQ(num_failures_before_call + 1u, ble_initiator_failures_.size());
    EXPECT_EQ(device_id_pair, ble_initiator_failures_.back().first);
    EXPECT_EQ(BleInitiatorFailureType::kCouldNotGenerateAdvertisement,
              ble_initiator_failures_.back().second);
  }

  // Returns the SecureChannel created by this call.
  FakeSecureChannelConnection* SimulateConnectionEstablished(
      multidevice::RemoteDeviceRef remote_device,
      ConnectionRole connection_role) {
    auto mock_bluetooth_device = std::make_unique<device::MockBluetoothDevice>(
        mock_adapter_.get(), 0u /* bluetooth_class */, "name", "address",
        false /* paired */, false /* connected */);
    fake_weave_client_connection_factory_->set_expected_bluetooth_device(
        mock_bluetooth_device.get());

    fake_ble_scanner()->NotifyReceivedAdvertisementFromDevice(
        remote_device, mock_bluetooth_device.get(), connection_role);

    // As a result of the connection, all ongoing connection attmepts should
    // have been canceled, since a connection is in progress.
    EXPECT_TRUE(fake_ble_advertiser()
                    ->GetAllRequestsForRemoteDevice(remote_device.GetDeviceId())
                    .empty());
    EXPECT_TRUE(
        fake_ble_scanner()
            ->GetAllScanFiltersForRemoteDevice(remote_device.GetDeviceId())
            .empty());

    FakeSecureChannelConnection* last_created_secure_channel =
        fake_secure_channel_factory_->last_created_instance();
    EXPECT_TRUE(last_created_secure_channel->was_initialized());
    return last_created_secure_channel;
  }

  void SimulateSecureChannelDisconnection(
      const std::string& remote_device_id,
      bool fail_during_authentication,
      FakeSecureChannelConnection* fake_secure_channel,
      size_t num_initiator_attempts_canceled_from_disconnection = 0u,
      size_t num_listener_attempts_canceled_from_disconnection = 0u) {
    size_t num_ble_initiator_failures_before_call =
        ble_initiator_failures_.size();
    size_t num_ble_listener_failures_before_call =
        ble_listener_failures_.size();

    // Connect, then disconnect. If needed, start authenticating before
    // disconnecting.
    fake_secure_channel->ChangeStatus(SecureChannel::Status::CONNECTED);
    if (fail_during_authentication) {
      fake_secure_channel->ChangeStatus(SecureChannel::Status::AUTHENTICATING);
    }
    fake_secure_channel->ChangeStatus(SecureChannel::Status::DISCONNECTED);

    // Iterate through all pending requests to |remote_device_id|, ensuring that
    // all expected failures have been communicated back to the client.
    size_t initiator_failures_index =
        num_ble_initiator_failures_before_call +
        num_initiator_attempts_canceled_from_disconnection;
    size_t listener_failure_index =
        num_ble_listener_failures_before_call +
        num_listener_attempts_canceled_from_disconnection;
    for (const auto& tuple :
         remote_device_id_to_metadata_map_[remote_device_id]) {
      switch (std::get<1>(tuple)) {
        case ConnectionRole::kInitiatorRole: {
          EXPECT_EQ(std::get<0>(tuple),
                    ble_initiator_failures_[initiator_failures_index].first);
          EXPECT_EQ(fail_during_authentication
                        ? BleInitiatorFailureType::kAuthenticationError
                        : BleInitiatorFailureType::kGattConnectionError,
                    ble_initiator_failures_[initiator_failures_index].second);
          ++initiator_failures_index;
          break;
        }

        case ConnectionRole::kListenerRole: {
          if (!fail_during_authentication)
            continue;

          EXPECT_EQ(std::get<0>(tuple),
                    ble_listener_failures_[listener_failure_index].first);
          EXPECT_EQ(BleListenerFailureType::kAuthenticationError,
                    ble_listener_failures_[listener_failure_index].second);
          ++listener_failure_index;
          break;
        }
      }
    }
    EXPECT_EQ(initiator_failures_index, ble_initiator_failures_.size());
    EXPECT_EQ(listener_failure_index, ble_listener_failures_.size());

    // All requests which were paused during the connection should have started
    // back up again, since the connection became disconnected.
    for (const auto& tuple :
         remote_device_id_to_metadata_map_[remote_device_id]) {
      switch (std::get<1>(tuple)) {
        case ConnectionRole::kInitiatorRole: {
          EXPECT_EQ(std::get<2>(tuple),
                    *fake_ble_advertiser()->GetPriorityForRequest(
                        std::get<0>(tuple)));
          EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
              std::get<0>(tuple), ConnectionRole::kInitiatorRole)));
          break;
        }

        case ConnectionRole::kListenerRole: {
          EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
              std::get<0>(tuple), ConnectionRole::kListenerRole)));
          break;
        }
      }
    }
  }

  void SimulateSecureChannelAuthentication(
      const std::string& remote_device_id,
      FakeSecureChannelConnection* fake_secure_channel,
      bool created_via_background_advertisement) {
    fake_authenticated_channel_factory_->SetExpectationsForNextCall(
        fake_secure_channel, created_via_background_advertisement);

    size_t num_success_callbacks_before_call = successful_connections_.size();

    test_clock()->Advance(kAdvertisementToConnectionTime);
    fake_secure_channel->ChangeStatus(SecureChannel::Status::CONNECTED);
    fake_secure_channel->ChangeStatus(SecureChannel::Status::AUTHENTICATING);

    test_clock()->Advance(kConnectionToAuthenticationTime);
    fake_secure_channel->ChangeStatus(SecureChannel::Status::AUTHENTICATED);

    // Verify that the callback was made. Verification that the provided
    // DeviceIdPair was correct occurs in OnConnectionSuccess().
    EXPECT_EQ(num_success_callbacks_before_call + 1u,
              successful_connections_.size());

    // For all remaining requests, verify that they were added back.
    for (const auto& tuple :
         remote_device_id_to_metadata_map_[remote_device_id]) {
      switch (std::get<1>(tuple)) {
        case ConnectionRole::kInitiatorRole: {
          EXPECT_EQ(std::get<2>(tuple),
                    *fake_ble_advertiser()->GetPriorityForRequest(
                        std::get<0>(tuple)));
          EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
              std::get<0>(tuple), ConnectionRole::kInitiatorRole)));
          break;
        }

        case ConnectionRole::kListenerRole: {
          EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
              std::get<0>(tuple), ConnectionRole::kListenerRole)));
          break;
        }
      }
    }
  }

  bool WasChannelHandledByDisconnector(
      FakeSecureChannelConnection* fake_secure_channel) {
    return fake_secure_channel_disconnector()->WasChannelHandled(
        fake_secure_channel);
  }

  base::test::TaskEnvironment task_environment_;
  const multidevice::RemoteDeviceRefList& test_devices() {
    return test_devices_;
  }

  base::SimpleTestClock* test_clock() { return test_clock_.get(); }

  base::HistogramTester* histogram_tester() { return &histogram_tester_; }

 private:
  void OnConnectionSuccess(
      const DeviceIdPair& device_id_pair,
      bool created_via_background_advertisement,
      std::unique_ptr<AuthenticatedChannel> authenticated_channel) {
    successful_connections_.push_back(
        std::make_pair(device_id_pair, std::move(authenticated_channel)));

    base::Optional<std::tuple<DeviceIdPair, ConnectionRole, ConnectionPriority>>
        tuple_which_received_callback;
    for (const auto& tuple :
         remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()]) {
      if (std::get<1>(tuple) == ConnectionRole::kInitiatorRole &&
          !created_via_background_advertisement) {
        EXPECT_EQ(std::get<0>(tuple), device_id_pair);
        tuple_which_received_callback = tuple;
        break;
      }

      if (std::get<1>(tuple) == ConnectionRole::kListenerRole &&
          created_via_background_advertisement) {
        EXPECT_EQ(std::get<0>(tuple), device_id_pair);
        tuple_which_received_callback = tuple;
        break;
      }
    }
    EXPECT_TRUE(tuple_which_received_callback);

    // The request which recieved the success callback is automatically removed
    // by BleConnectionManager, so it no longer needs to be tracked.
    remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()].erase(
        *tuple_which_received_callback);

    // Make a copy of the entries which should be canceled. This is required
    // because the Cancel*() calls below end up removing entries from
    // |remote_device_id_to_metadata_map_|, which can cause access to deleted
    // memory.
    base::flat_set<std::tuple<DeviceIdPair, ConnectionRole, ConnectionPriority>>
        to_cancel = remote_device_id_to_metadata_map_[device_id_pair
                                                          .remote_device_id()];

    for (const auto& tuple : to_cancel) {
      switch (std::get<1>(tuple)) {
        case ConnectionRole::kInitiatorRole:
          CancelBleInitiatorConnectionAttempt(std::get<0>(tuple));
          break;

        case ConnectionRole::kListenerRole:
          CancelBleListenerConnectionAttempt(std::get<0>(tuple));
          break;
      }
    }
  }

  void OnBleInitiatorFailure(const DeviceIdPair& device_id_pair,
                             bool should_cancel_attempt_on_failure,
                             BleInitiatorFailureType failure_type) {
    ble_initiator_failures_.push_back(
        std::make_pair(device_id_pair, failure_type));
    if (!should_cancel_attempt_on_failure)
      return;

    // Make a copy of the pair before canceling the attempt, since the reference
    // points to memory owned by |manager_| which will be deleted.
    DeviceIdPair device_id_pair_copy = device_id_pair;
    CancelBleInitiatorConnectionAttempt(device_id_pair_copy);
  }

  void OnBleListenerFailure(const DeviceIdPair& device_id_pair,
                            bool should_cancel_attempt_on_failure,
                            BleListenerFailureType failure_type) {
    ble_listener_failures_.push_back(
        std::make_pair(device_id_pair, failure_type));
    if (!should_cancel_attempt_on_failure)
      return;

    // Make a copy of the pair before canceling the attempt, since the reference
    // points to memory owned by |manager_| which will be deleted.
    DeviceIdPair device_id_pair_copy = device_id_pair;
    CancelBleListenerConnectionAttempt(device_id_pair_copy);
  }

  void SetInRemoteDeviceIdToMetadataMap(
      const DeviceIdPair& device_id_pair,
      ConnectionRole connection_role,
      ConnectionPriority connection_priority) {
    // If the entry already exists, update its priority.
    for (auto& tuple :
         remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()]) {
      if (std::get<0>(tuple) == device_id_pair &&
          std::get<1>(tuple) == connection_role) {
        std::get<2>(tuple) = connection_priority;
        return;
      }
    }

    // Otherwise, add a new entry.
    remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()].insert(
        std::make_tuple(device_id_pair, connection_role, connection_priority));
  }

  void RemoveFromRemoteDeviceIdToMetadataMap(const DeviceIdPair& device_id_pair,
                                             ConnectionRole connection_role) {
    base::flat_set<std::tuple<DeviceIdPair, ConnectionRole,
                              ConnectionPriority>>& set_for_remote_device =
        remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()];

    for (auto it = set_for_remote_device.begin();
         it != set_for_remote_device.end(); ++it) {
      if (std::get<0>(*it) == device_id_pair &&
          std::get<1>(*it) == connection_role) {
        set_for_remote_device.erase(it);
        return;
      }
    }

    NOTREACHED();
  }

  FakeBleAdvertiser* fake_ble_advertiser() {
    return fake_ble_advertiser_factory_->instance();
  }

  FakeBleScanner* fake_ble_scanner() {
    return fake_ble_scanner_factory_->instance();
  }

  FakeSecureChannelDisconnector* fake_secure_channel_disconnector() {
    return fake_secure_channel_disconnector_factory_->instance();
  }

  const multidevice::RemoteDeviceRefList test_devices_;

  base::HistogramTester histogram_tester_;

  base::flat_map<
      std::string,
      base::flat_set<
          std::tuple<DeviceIdPair, ConnectionRole, ConnectionPriority>>>
      remote_device_id_to_metadata_map_;

  std::vector<std::pair<DeviceIdPair, std::unique_ptr<AuthenticatedChannel>>>
      successful_connections_;
  std::vector<std::pair<DeviceIdPair, BleInitiatorFailureType>>
      ble_initiator_failures_;
  std::vector<std::pair<DeviceIdPair, BleListenerFailureType>>
      ble_listener_failures_;

  std::unique_ptr<FakeBleSynchronizerFactory> fake_ble_synchronizer_factory_;
  std::unique_ptr<FakeBleAdvertiserFactory> fake_ble_advertiser_factory_;
  std::unique_ptr<FakeBleScannerFactory> fake_ble_scanner_factory_;
  std::unique_ptr<FakeSecureChannelDisconnectorFactory>
      fake_secure_channel_disconnector_factory_;
  std::unique_ptr<FakeWeaveClientConnectionFactory>
      fake_weave_client_connection_factory_;
  std::unique_ptr<FakeSecureChannelFactory> fake_secure_channel_factory_;
  std::unique_ptr<FakeAuthenticatedChannelFactory>
      fake_authenticated_channel_factory_;

  scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>> mock_adapter_;
  std::unique_ptr<FakeBleServiceDataHelper> fake_ble_service_data_helper_;
  std::unique_ptr<FakeTimerFactory> fake_timer_factory_;
  std::unique_ptr<base::SimpleTestClock> test_clock_;

  std::unique_ptr<BleConnectionManager> manager_;

  DISALLOW_COPY_AND_ASSIGN(SecureChannelBleConnectionManagerImplTest);
};

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Initiator_UpdatePriority) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);
  UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kMedium,
                                       true /* expected_to_update_priority */);
  UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kHigh,
                                       true /* expected_to_update_priority */);
  UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kLow,
                                       true /* expected_to_update_priority */);
  UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kMedium,
                                       true /* expected_to_update_priority */);
  UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kHigh,
                                       true /* expected_to_update_priority */);

  CancelBleInitiatorConnectionAttempt(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Initiator_AdvertisementsUnansweredThenCanceled) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);
  UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kMedium,
                                       true /* expected_to_update_priority */);

  // Fail a few times due to timeouts.
  SimulateBleSlotEnding(pair,
                        false /* replaced_by_higher_priority_advertisement */);
  SimulateBleSlotEnding(pair,
                        false /* replaced_by_higher_priority_advertisement */);
  SimulateBleSlotEnding(pair,
                        false /* replaced_by_higher_priority_advertisement */);

  CancelBleInitiatorConnectionAttempt(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Initiator_FailToGenerateAdvertisement_ManualCleanup) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);
  SimulateBleFailureToGenerateAdvertisement(pair);
  CancelBleInitiatorConnectionAttempt(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Initiator_FailToGenerateAdvertisement_CleanupOnCallback) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                true /* should_cancel_attempt_on_failure */);
  SimulateBleFailureToGenerateAdvertisement(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Initiator_FailsAuthenticationThenCanceled) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelDisconnection(pair.remote_device_id(),
                                     true /* fail_during_authentication */,
                                     fake_secure_channel);

  CancelBleInitiatorConnectionAttempt(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Initiator_FailsAuthenticationThenCanceled_CleanupOnCallback) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                true /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelDisconnection(
      pair.remote_device_id(), true /* fail_during_authentication */,
      fake_secure_channel,
      1u /* num_initiator_attempts_canceled_from_disconnection */,
      0u /* num_listener_attempts_canceled_from_disconnection */);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Initiator_GattFailureThenCanceled) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelDisconnection(pair.remote_device_id(),
                                     false /* fail_during_authentication */,
                                     fake_secure_channel);

  CancelBleInitiatorConnectionAttempt(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Initiator_SuccessfulConnection) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelAuthentication(
      pair.remote_device_id(), fake_secure_channel,
      false /* created_via_background_advertisement */);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Listener_UpdatePriority) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);
  UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kMedium,
                                      true /* expected_to_update_priority */);
  UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kHigh,
                                      true /* expected_to_update_priority */);
  UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kLow,
                                      true /* expected_to_update_priority */);
  UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kMedium,
                                      true /* expected_to_update_priority */);
  UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kHigh,
                                      true /* expected_to_update_priority */);

  CancelBleListenerConnectionAttempt(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Listener_FailsAuthenticationThenCanceled) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kListenerRole);
  SimulateSecureChannelDisconnection(pair.remote_device_id(),
                                     true /* fail_during_authentication */,
                                     fake_secure_channel);

  CancelBleListenerConnectionAttempt(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Listener_FailsAuthenticationThenCanceled_CleanupOnCallback) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               true /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kListenerRole);
  SimulateSecureChannelDisconnection(
      pair.remote_device_id(), true /* fail_during_authentication */,
      fake_secure_channel,
      0u /* num_initiator_attempts_canceled_from_disconnection */,
      1u /* num_listener_attempts_canceled_from_disconnection */);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Listener_GattFailureThenCanceled) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kListenerRole);
  SimulateSecureChannelDisconnection(pair.remote_device_id(),
                                     false /* fail_during_authentication */,
                                     fake_secure_channel);

  CancelBleListenerConnectionAttempt(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       OneRequest_Listener_SuccessfulConnection) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kListenerRole);
  SimulateSecureChannelAuthentication(
      pair.remote_device_id(), fake_secure_channel,
      true /* created_via_background_advertisement */);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       TwoRequests_BothInitiator_Failures) {
  DeviceIdPair pair_1(test_devices()[1].GetDeviceId(),
                      test_devices()[0].GetDeviceId());
  DeviceIdPair pair_2(test_devices()[2].GetDeviceId(),
                      test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair_1, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);
  AttemptBleInitiatorConnection(pair_2, ConnectionPriority::kMedium,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);

  // One advertisement slot failure each.
  SimulateBleSlotEnding(pair_1,
                        false /* replaced_by_higher_priority_advertisement */);
  SimulateBleSlotEnding(pair_2,
                        false /* replaced_by_higher_priority_advertisement */);

  // For pair_1, establish a connection then fail due to GATT errors.
  FakeSecureChannelConnection* fake_secure_channel_1 =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelDisconnection(pair_1.remote_device_id(),
                                     false /* fail_during_authentication */,
                                     fake_secure_channel_1);

  // For pair_2, establish a connection then fail due to authentication errors.
  FakeSecureChannelConnection* fake_secure_channel_2 =
      SimulateConnectionEstablished(test_devices()[2],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelDisconnection(pair_2.remote_device_id(),
                                     true /* fail_during_authentication */,
                                     fake_secure_channel_2);

  // Cancel both attempts.
  CancelBleInitiatorConnectionAttempt(pair_1);
  CancelBleInitiatorConnectionAttempt(pair_2);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       TwoRequests_BothInitiator_Success) {
  DeviceIdPair pair_1(test_devices()[1].GetDeviceId(),
                      test_devices()[0].GetDeviceId());
  DeviceIdPair pair_2(test_devices()[2].GetDeviceId(),
                      test_devices()[0].GetDeviceId());

  AttemptBleInitiatorConnection(pair_1, ConnectionPriority::kLow,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);
  AttemptBleInitiatorConnection(pair_2, ConnectionPriority::kMedium,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel_1 =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelAuthentication(
      pair_1.remote_device_id(), fake_secure_channel_1,
      false /* created_via_background_advertisement */);

  FakeSecureChannelConnection* fake_secure_channel_2 =
      SimulateConnectionEstablished(test_devices()[2],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelAuthentication(
      pair_2.remote_device_id(), fake_secure_channel_2,
      false /* created_via_background_advertisement */);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       TwoRequests_BothListener_Failures) {
  DeviceIdPair pair_1(test_devices()[1].GetDeviceId(),
                      test_devices()[0].GetDeviceId());
  DeviceIdPair pair_2(test_devices()[2].GetDeviceId(),
                      test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair_1, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);
  AttemptBleListenerConnection(pair_2, ConnectionPriority::kMedium,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel_1 =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kListenerRole);
  SimulateSecureChannelDisconnection(pair_1.remote_device_id(),
                                     true /* fail_during_authentication */,
                                     fake_secure_channel_1);

  FakeSecureChannelConnection* fake_secure_channel_2 =
      SimulateConnectionEstablished(test_devices()[2],
                                    ConnectionRole::kListenerRole);
  SimulateSecureChannelDisconnection(pair_2.remote_device_id(),
                                     true /* fail_during_authentication */,
                                     fake_secure_channel_2);

  CancelBleListenerConnectionAttempt(pair_1);
  CancelBleListenerConnectionAttempt(pair_2);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       TwoRequests_BothListener_Success) {
  DeviceIdPair pair_1(test_devices()[1].GetDeviceId(),
                      test_devices()[0].GetDeviceId());
  DeviceIdPair pair_2(test_devices()[2].GetDeviceId(),
                      test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair_1, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);
  AttemptBleListenerConnection(pair_2, ConnectionPriority::kMedium,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel_1 =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kListenerRole);
  SimulateSecureChannelAuthentication(
      pair_1.remote_device_id(), fake_secure_channel_1,
      true /* created_via_background_advertisement */);

  FakeSecureChannelConnection* fake_secure_channel_2 =
      SimulateConnectionEstablished(test_devices()[2],
                                    ConnectionRole::kListenerRole);
  SimulateSecureChannelAuthentication(
      pair_2.remote_device_id(), fake_secure_channel_2,
      true /* created_via_background_advertisement */);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       TwoRequests_SamePairDifferentRole_Failure) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);
  AttemptBleInitiatorConnection(pair, ConnectionPriority::kMedium,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);

  // GATT failure.
  FakeSecureChannelConnection* fake_secure_channel_1 =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelDisconnection(pair.remote_device_id(),
                                     false /* fail_during_authentication */,
                                     fake_secure_channel_1);

  // Authentication failure.
  FakeSecureChannelConnection* fake_secure_channel_2 =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kListenerRole);
  SimulateSecureChannelDisconnection(pair.remote_device_id(),
                                     true /* fail_during_authentication */,
                                     fake_secure_channel_2);

  CancelBleListenerConnectionAttempt(pair);
  CancelBleInitiatorConnectionAttempt(pair);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       TwoRequests_SamePairDifferentRole_Success) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);
  AttemptBleInitiatorConnection(pair, ConnectionPriority::kMedium,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);
  SimulateSecureChannelAuthentication(
      pair.remote_device_id(), fake_secure_channel,
      false /* created_via_background_advertisement */);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       TwoRequests_SamePairDifferentRole_NewAttemptWhileConnectionInProgress) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);

  // There is already a connection in progress, so this is not expected to add
  // a request to BleAdvertiser/BleScanner.
  AttemptBleInitiatorConnection(pair, ConnectionPriority::kMedium,
                                false /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);

  // Update the priority; this also should not cause an update in BleScanner.
  UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kMedium,
                                      false /* expected_to_add_request */);

  SimulateSecureChannelAuthentication(
      pair.remote_device_id(), fake_secure_channel,
      false /* created_via_background_advertisement */);
}

TEST_F(SecureChannelBleConnectionManagerImplTest,
       TwoRequests_RemoveRequestWhileAuthenticating) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);
  AttemptBleInitiatorConnection(pair, ConnectionPriority::kMedium,
                                true /* expected_to_add_request */,
                                false /* should_cancel_attempt_on_failure */);

  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kInitiatorRole);

  // Before the channel authenticates, remove both ongoing attempts. This should
  // cause the ongoing connection to be passed off to the
  // SecureChannelDisconnector.
  CancelBleListenerConnectionAttempt(pair);
  CancelBleInitiatorConnectionAttempt(pair);

  EXPECT_TRUE(WasChannelHandledByDisconnector(fake_secure_channel));
}

TEST_F(SecureChannelBleConnectionManagerImplTest, ConnectionMetrics) {
  DeviceIdPair pair(test_devices()[1].GetDeviceId(),
                    test_devices()[0].GetDeviceId());

  // Start a connection attempt and advance the clock.
  AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
                               true /* expected_to_add_request */,
                               false /* should_cancel_attempt_on_failure */);

  test_clock()->Advance(kScanToAdvertisementTime);

  // Simulate a connection being established, then disconnected.
  FakeSecureChannelConnection* fake_secure_channel =
      SimulateConnectionEstablished(test_devices()[1],
                                    ConnectionRole::kListenerRole);
  test_clock()->Advance(kAdvertisementToConnectionTime);
  SimulateSecureChannelDisconnection(pair.remote_device_id(),
                                     false /* fail_during_authentication */,
                                     fake_secure_channel);
  histogram_tester()->ExpectTimeBucketCount(
      "MultiDevice.SecureChannel.BLE.Performance."
      "StartScanToReceiveAdvertisementDuration.Background",
      kScanToAdvertisementTime, 1);
  histogram_tester()->ExpectTimeBucketCount(
      "MultiDevice.SecureChannel.BLE.Performance."
      "ReceiveAdvertisementToConnectionDuration.Background",
      kAdvertisementToConnectionTime, 1);
  histogram_tester()->ExpectTimeBucketCount(
      "MultiDevice.SecureChannel.BLE.Performance."
      "StartScanToConnectionDuration.Background",
      kScanToAdvertisementTime + kAdvertisementToConnectionTime, 1);
  histogram_tester()->ExpectBucketCount(
      "MultiDevice.SecureChannel.BLE.ReceiveAdvertisementToGattConnection."
      "EffectiveSuccessRateWithRetries",
      true, 1u /* expected_count */);

  // Advance the clock again, then simulate a successful authentication.
  test_clock()->Advance(kScanToAdvertisementTime);
  fake_secure_channel = SimulateConnectionEstablished(
      test_devices()[1], ConnectionRole::kListenerRole);
  SimulateSecureChannelAuthentication(
      pair.remote_device_id(), fake_secure_channel,
      true /* created_via_background_advertisement */);

  histogram_tester()->ExpectTimeBucketCount(
      "MultiDevice.SecureChannel.BLE.Performance."
      "StartScanToReceiveAdvertisementDuration.Background",
      kScanToAdvertisementTime, 2);
  histogram_tester()->ExpectTimeBucketCount(
      "MultiDevice.SecureChannel.BLE.Performance."
      "ReceiveAdvertisementToConnectionDuration.Background",
      kAdvertisementToConnectionTime, 2);
  histogram_tester()->ExpectTimeBucketCount(
      "MultiDevice.SecureChannel.BLE.Performance."
      "StartScanToConnectionDuration.Background",
      kScanToAdvertisementTime + kAdvertisementToConnectionTime, 2);
  histogram_tester()->ExpectTimeBucketCount(
      "MultiDevice.SecureChannel.BLE.Performance."
      "ConnectionToAuthenticationDuration.Background",
      kConnectionToAuthenticationTime, 1);
  histogram_tester()->ExpectBucketCount(
      "MultiDevice.SecureChannel.BLE.ReceiveAdvertisementToGattConnection."
      "EffectiveSuccessRateWithRetries",
      true, 2u /* expected_count */);
  histogram_tester()->ExpectBucketCount(
      "MultiDevice.SecureChannel.BLE.ReceiveAdvertisementToAuthentication."
      "EffectiveSuccessRateWithRetries",
      true, 1u /* expected_count */);
  histogram_tester()->ExpectBucketCount(
      "MultiDevice.SecureChannel.BLE.GattConnectionToAuthentication."
      "EffectiveSuccessRateWithRetries",
      true, 1u /* expected_count */);
}

}  // namespace secure_channel

}  // namespace chromeos
