#include <pw_unit_test/framework.h>

#include <controller/CHIPDeviceControllerFactory.h>
#include <controller/tests/DeviceCommissionerTestAccess.h>
#include <controller/tests/SetUpCodePairerTestAccess.h>
#include <credentials/GroupDataProviderImpl.h>
#include <credentials/PersistentStorageOpCertStore.h>
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
#include <crypto/DefaultSessionKeystore.h>
#include <data-model-providers/codegen/Instance.h>
#include <lib/support/TestPersistentStorageDelegate.h>
#include <platform/CHIPDeviceLayer.h>

#include <atomic>
#include <chrono>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <thread>

#if CONFIG_NETWORK_LAYER_BLE && CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
#include <ble/Ble.h>
#include <platform/Linux/BLEManagerImpl.h>
#include <platform/Linux/bluez/BluezConnection.h>

namespace chip::DeviceLayer::Internal {
class BLEManagerImplTestAccess
{
public:
    static Ble::BleLayer & Layer(BLEManagerImpl & manager) { return manager; }
    static CHIP_ERROR InstallBackend(BLEManagerImpl & manager)
    {
        manager.Ble::BleLayer::Shutdown();
        return manager.Ble::BleLayer::Init(&manager, &manager, &manager, &SystemLayer());
    }

    static void Request(BLEManagerImpl & manager, unsigned & callbacks)
    {
        manager.mServiceMode                                     = ConnectivityManager::kCHIPoBLEServiceMode_Disabled;
        manager.Ble::BleConnectionDelegate::OnConnectionComplete = [](void * context, BLE_CONNECTION_OBJECT) {
            ++*static_cast<unsigned *>(context);
        };
        manager.Ble::BleConnectionDelegate::OnConnectionError = [](void * context, CHIP_ERROR) {
            ++*static_cast<unsigned *>(context);
        };
        manager.NewConnection(nullptr, &callbacks, SetupDiscriminator());
    }
    static CHIP_ERROR Cancel(BLEManagerImpl & manager) { return manager.CancelConnection(); }
    static void InstallScanningAdapter(BLEManagerImpl & manager, BluezAdapter1 * adapter)
    {
        auto & scanner = manager.mDeviceScanner;
        ASSERT_EQ(scanner.Init(adapter, &manager), CHIP_NO_ERROR);
        ASSERT_EQ(manager.mBluezObjectManager.SubscribeDeviceNotifications(adapter, &scanner), CHIP_NO_ERROR);
        scanner.mCancellable.reset(g_cancellable_new());
        scanner.mScannerState                = ChipDeviceScanner::ChipDeviceScannerState::SCANNING;
        manager.mBLEScanConfig.mBleScanState = BleScanState::kScanForDiscriminator;
    }
    static bool ScannerActive(BLEManagerImpl & manager) { return manager.mDeviceScanner.IsScanning(); }
    static void Scanning(BLEManagerImpl & manager)
    {
        ++manager.mScanRequestId;
        manager.mIsCentral                   = true;
        manager.mBLEScanConfig.mBleScanState = BleScanState::kScanForDiscriminator;
    }
    static CHIP_ERROR StartScan(BLEManagerImpl & manager, BluezAdapter1 * adapter)
    {
        Scanning(manager);
        ReturnErrorOnFailure(manager.mDeviceScanner.Init(adapter, &manager));
        return manager.mDeviceScanner.StartScan();
    }
    static void Scanned(BLEManagerImpl & manager, BluezDevice1 & device, const Ble::ChipBLEDeviceIdentificationInfo & info)
    {
        manager.OnDeviceScanned(device, info);
    }
    static bool IsConnecting(BLEManagerImpl & manager) { return manager.mBLEScanConfig.mBleScanState == BleScanState::kConnecting; }
    static BluezEndpoint & Connecting(BLEManagerImpl & manager, BluezDevice1 * device = nullptr)
    {
        uint64_t requestId;
        {
            StackLock lock;
            requestId = ++manager.mScanRequestId;
            manager.mEndpoint.PrepareConnect();
            manager.mIsCentral                   = true;
            manager.mBLEScanConfig.mBleScanState = BleScanState::kConnecting;
        }
        if (device != nullptr)
        {
            EXPECT_EQ(manager.mEndpoint.ConnectDevice(*device, requestId), CHIP_NO_ERROR);
        }
        return manager.mEndpoint;
    }
    static void RestorePeripheral(BLEManagerImpl & manager) { manager.mIsCentral = false; }
    static GCancellable * ConnectCancellable(BluezEndpoint & endpoint) { return endpoint.mConnectCancellable.get(); }
    static BluezEndpoint & InstallGatt(BLEManagerImpl & manager, GDBusObjectManager * objects)
    {
        manager.mBluezObjectManager.mObjectManager.reset(G_DBUS_OBJECT_MANAGER(g_object_ref(objects)));
        manager.mEndpoint.mIsCentral = true;
        return manager.mEndpoint;
    }
    static void RemoveGatt(BLEManagerImpl & manager)
    {
        manager.mBluezObjectManager.mObjectManager.reset();
        manager.mEndpoint.mIsCentral = false;
        manager.mIsCentral           = false;
    }
    static uint64_t PendingTicket(BluezEndpoint & endpoint)
    {
        return endpoint.mConnMap.empty() ? 0 : endpoint.mConnMap.begin()->second.mPendingTicket;
    }
    static ChipDeviceEvent PendingEvent(BLEManagerImpl & manager)
    {
        return { .Type     = DeviceEventType::kPlatformLinuxBLECentralConnected,
                 .Platform = { .BLECentralConnected = { .mPendingTicket = PendingTicket(manager.mEndpoint),
                                                        .mRequestId     = manager.mScanRequestId.load() } } };
    }
    static void ExpireConnect(BLEManagerImpl & manager)
    {
        StackLock lock;
        BLEManagerImpl::HandleConnectTimer(nullptr, &manager);
    }
    static void Dispatch(BLEManagerImpl & manager, const ChipDeviceEvent & event)
    {
        StackLock lock;
        manager._OnPlatformEvent(&event);
    }
};
} // namespace chip::DeviceLayer::Internal

using namespace chip;
using namespace chip::Controller;

namespace {

constexpr uint16_t kDiscriminator = 0xABC;

struct PrivateBluezPeer
{
    std::unique_ptr<GDBusServer, decltype(&g_object_unref)> listener{ nullptr, g_object_unref };
    std::unique_ptr<GDBusConnection, decltype(&g_object_unref)> server{ nullptr, g_object_unref };
    std::unique_ptr<GDBusConnection, decltype(&g_object_unref)> client{ nullptr, g_object_unref };
    std::mutex mutex;
    std::condition_variable connected;

    ~PrivateBluezPeer()
    {
        if (listener)
        {
            EXPECT_EQ(DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(
                          +[](PrivateBluezPeer * peer) {
                              g_dbus_server_stop(peer->listener.get());
                              return CHIP_NO_ERROR;
                          },
                          this),
                      CHIP_NO_ERROR);
        }
        if (client)
        {
            g_dbus_connection_close_sync(client.get(), nullptr, nullptr);
        }
        if (server)
        {
            g_dbus_connection_close_sync(server.get(), nullptr, nullptr);
        }
    }

    CHIP_ERROR Start()
    {
        ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(
            +[](PrivateBluezPeer * peer) {
                GAutoPtr<gchar> guid(g_dbus_generate_guid());
                GAutoPtr<GError> error;
                peer->listener.reset(g_dbus_server_new_sync("unix:tmpdir=/tmp", G_DBUS_SERVER_FLAGS_NONE, guid.get(), nullptr,
                                                            nullptr, &error.GetReceiver()));
                VerifyOrReturnError(peer->listener != nullptr, CHIP_ERROR_INTERNAL);
                g_signal_connect(
                    peer->listener.get(), "new-connection",
                    G_CALLBACK(+[](GDBusServer *, GDBusConnection * connection, PrivateBluezPeer * accepted) -> gboolean {
                        std::lock_guard<std::mutex> lock(accepted->mutex);
                        accepted->server.reset(G_DBUS_CONNECTION(g_object_ref(connection)));
                        accepted->connected.notify_one();
                        return TRUE;
                    }),
                    peer);
                g_dbus_server_start(peer->listener.get());
                return CHIP_NO_ERROR;
            },
            this));
        GAutoPtr<GError> error;
        client.reset(g_dbus_connection_new_for_address_sync(g_dbus_server_get_client_address(listener.get()),
                                                            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, nullptr, nullptr,
                                                            &error.GetReceiver()));
        VerifyOrReturnError(client != nullptr, CHIP_ERROR_INTERNAL);
        std::unique_lock<std::mutex> lock(mutex);
        VerifyOrReturnError(connected.wait_for(lock, std::chrono::seconds(5), [this] { return server != nullptr; }),
                            CHIP_ERROR_TIMEOUT);
        return CHIP_NO_ERROR;
    }
};

struct Connection
{
    bool retired    = false;
    unsigned closes = 0;
    unsigned writes = 0;

    BLE_CONNECTION_OBJECT Object() { return reinterpret_cast<BLE_CONNECTION_OBJECT>(this); }
};

struct PrivateBluezGattPeer : PrivateBluezPeer
{
    static constexpr const char * kDevicePath = "/org/bluez/device";
    GAutoPtr<GDBusObjectManagerServer> root;
    GAutoPtr<GDBusObjectManager> objects;
    GAutoPtr<BluezDevice1> device;
    GAutoPtr<BluezDevice1> proxy;
    GAutoPtr<BluezAdapter1> adapter;
    DeviceLayer::Internal::BluezEndpoint * endpoint = nullptr;
    std::atomic<unsigned> disconnects{ 0 };
    std::atomic<unsigned> connects{ 0 };
    std::atomic<unsigned> scanStarts{ 0 };
    std::atomic<unsigned> scanStops{ 0 };
    guint discoveryFilter       = 0;
    bool disconnectChangesState = true;
    std::thread serviceThread;
    GMainLoop * serviceLoop = nullptr;
    bool ready              = false;
    bool observedConnected  = true;
    bool observedResolved   = false;
    size_t connections      = 0;

    ~PrivateBluezGattPeer()
    {
        if (discoveryFilter != 0)
        {
            g_dbus_connection_remove_filter(server.get(), discoveryFilter);
        }
        if (endpoint != nullptr)
        {
            EXPECT_EQ(DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(
                          +[](PrivateBluezGattPeer * peer) {
                              g_signal_handlers_disconnect_by_data(peer->objects.get(), peer);
                              g_dbus_proxy_set_cached_property(G_DBUS_PROXY(peer->proxy.get()), "Connected",
                                                               g_variant_new_boolean(FALSE));
                              peer->endpoint->OnDevicePropertyChanged(*peer->proxy, nullptr, nullptr);
                              DeviceLayer::Internal::BLEManagerImplTestAccess::RemoveGatt(DeviceLayer::Internal::BLEMgrImpl());
                              return CHIP_NO_ERROR;
                          },
                          this),
                      CHIP_NO_ERROR);
            DrainEvents();
        }
        if (serviceThread.joinable())
        {
            g_main_loop_quit(serviceLoop);
            serviceThread.join();
        }
    }

    static void DrainEvents()
    {
        ASSERT_EQ(DeviceLayer::PlatformMgr().ScheduleWork(
                      [](intptr_t) { EXPECT_EQ(DeviceLayer::PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
                  CHIP_NO_ERROR);
        DeviceLayer::PlatformMgr().RunEventLoop();
    }

    CHIP_ERROR Attach()
    {
        return DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(
            +[](PrivateBluezGattPeer * peer) {
                using namespace DeviceLayer::Internal;
                peer->endpoint = &BLEManagerImplTestAccess::InstallGatt(BLEMgrImpl(), peer->objects.get());
                std::unique_ptr<GDBusObject, decltype(&g_object_unref)> object(
                    g_dbus_object_manager_get_object(peer->objects.get(), kDevicePath), g_object_unref);
                peer->proxy.reset(bluez_object_get_device1(BLUEZ_OBJECT(object.get())));
                g_signal_connect(
                    peer->objects.get(), "interface-proxy-properties-changed",
                    G_CALLBACK(+[](GDBusObjectManagerClient *, GDBusObjectProxy *, GDBusProxy * interface, GVariant * changed,
                                   const gchar * const * invalidated, PrivateBluezGattPeer * owner) {
                        if (BLUEZ_IS_DEVICE1(interface))
                        {
                            owner->endpoint->OnDevicePropertyChanged(*BLUEZ_DEVICE1(interface), changed, invalidated);
                            std::lock_guard<std::mutex> lock(owner->mutex);
                            owner->observedConnected = bluez_device1_get_connected(owner->proxy.get());
                            owner->observedResolved  = bluez_device1_get_services_resolved(owner->proxy.get());
                            owner->connections       = owner->endpoint->GetNumConnections();
                            owner->connected.notify_one();
                        }
                    }),
                    peer);
                return CHIP_NO_ERROR;
            },
            this);
    }

    bool WaitState(bool isConnected, bool resolved, size_t count)
    {
        std::unique_lock<std::mutex> lock(mutex);
        return connected.wait_for(lock, std::chrono::seconds(2), [=, this] {
            return observedConnected == isConnected && observedResolved == resolved && connections == count;
        });
    }

    CHIP_ERROR SetState(bool isConnected, bool resolved)
    {
        struct
        {
            PrivateBluezGattPeer * peer;
            bool isConnected;
            bool resolved;
        } state{ this, isConnected, resolved };
        return DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(
            +[](decltype(state) * update) {
                bluez_device1_set_connected(update->peer->device.get(), update->isConnected);
                bluez_device1_set_services_resolved(update->peer->device.get(), update->resolved);
                g_dbus_interface_skeleton_flush(G_DBUS_INTERFACE_SKELETON(update->peer->device.get()));
                return CHIP_NO_ERROR;
            },
            &state);
    }

    DeviceLayer::ChipDeviceEvent PendingEvent()
    {
        DeviceLayer::ChipDeviceEvent event{};
        EXPECT_EQ(DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(
                      +[](DeviceLayer::ChipDeviceEvent * pending) {
                          *pending =
                              DeviceLayer::Internal::BLEManagerImplTestAccess::PendingEvent(DeviceLayer::Internal::BLEMgrImpl());
                          return CHIP_NO_ERROR;
                      },
                      &event),
                  CHIP_NO_ERROR);
        return event;
    }

    bool WaitDisconnects(unsigned count)
    {
        std::unique_lock<std::mutex> lock(mutex);
        return connected.wait_for(lock, std::chrono::seconds(2), [=, this] { return disconnects.load() == count; });
    }

    CHIP_ERROR Start()
    {
        ReturnErrorOnFailure(PrivateBluezPeer::Start());
        discoveryFilter = g_dbus_connection_add_filter(
            server.get(),
            +[](GDBusConnection * connection, GDBusMessage * message, gboolean incoming, void * context) -> GDBusMessage * {
                if (incoming && g_dbus_message_get_message_type(message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL &&
                    g_strcmp0(g_dbus_message_get_interface(message), "org.bluez.Adapter1") == 0)
                {
                    auto * peer = static_cast<PrivateBluezGattPeer *>(context);
                    if (g_strcmp0(g_dbus_message_get_member(message), "StartDiscovery") == 0)
                    {
                        ++peer->scanStarts;
                    }
                    if (g_strcmp0(g_dbus_message_get_member(message), "StopDiscovery") == 0)
                    {
                        ++peer->scanStops;
                    }
                    GDBusMessage * reply = g_dbus_message_new_method_reply(message);
                    g_dbus_connection_send_message(connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, nullptr, nullptr);
                    g_object_unref(reply);
                    g_object_unref(message);
                    return nullptr;
                }
                return message;
            },
            this, nullptr);
        serviceThread = std::thread([this] {
            auto * peer            = this;
            GMainContext * context = g_main_context_new();
            g_main_context_push_thread_default(context);
            serviceLoop = g_main_loop_new(context, FALSE);
            peer->root.reset(g_dbus_object_manager_server_new("/org/bluez"));
            peer->device.reset(bluez_device1_skeleton_new());
            bluez_device1_set_address(peer->device.get(), "00:11:22:33:44:55");
            bluez_device1_set_adapter(peer->device.get(), "/org/bluez/adapter");
            bluez_device1_set_connected(peer->device.get(), TRUE);
            bluez_device1_set_services_resolved(peer->device.get(), FALSE);
            std::unique_ptr<GDBusObject, decltype(&g_object_unref)> deviceObject(
                G_DBUS_OBJECT(bluez_object_skeleton_new(kDevicePath)), g_object_unref);
            bluez_object_skeleton_set_device1(BLUEZ_OBJECT_SKELETON(deviceObject.get()), peer->device.get());
            g_dbus_object_manager_server_export(peer->root.get(), G_DBUS_OBJECT_SKELETON(deviceObject.get()));
            g_signal_connect(peer->device.get(), "handle-connect",
                             G_CALLBACK(+[](BluezDevice1 * deviceProxy, GDBusMethodInvocation * invocation,
                                            PrivateBluezGattPeer * owner) -> gboolean {
                                 ++owner->connects;
                                 bluez_device1_complete_connect(deviceProxy, invocation);
                                 return TRUE;
                             }),
                             peer);
            g_signal_connect(peer->device.get(), "handle-disconnect",
                             G_CALLBACK(+[](BluezDevice1 * deviceProxy, GDBusMethodInvocation * invocation,
                                            PrivateBluezGattPeer * owner) -> gboolean {
                                 ++owner->disconnects;
                                 bluez_device1_complete_disconnect(deviceProxy, invocation);
                                 if (owner->disconnectChangesState)
                                 {
                                     bluez_device1_set_connected(deviceProxy, FALSE);
                                     g_dbus_interface_skeleton_flush(G_DBUS_INTERFACE_SKELETON(deviceProxy));
                                 }
                                 std::lock_guard<std::mutex> lock(owner->mutex);
                                 owner->connected.notify_one();
                                 return TRUE;
                             }),
                             peer);
            GAutoPtr<BluezGattService1> service(bluez_gatt_service1_skeleton_new());
            bluez_gatt_service1_set_uuid(service.get(), Ble::CHIP_BLE_SERVICE_LONG_UUID_STR);
            bluez_gatt_service1_set_device(service.get(), kDevicePath);
            std::unique_ptr<GDBusObject, decltype(&g_object_unref)> serviceObject(
                G_DBUS_OBJECT(bluez_object_skeleton_new("/org/bluez/device/service")), g_object_unref);
            bluez_object_skeleton_set_gatt_service1(BLUEZ_OBJECT_SKELETON(serviceObject.get()), service.get());
            g_dbus_object_manager_server_export(peer->root.get(), G_DBUS_OBJECT_SKELETON(serviceObject.get()));
            const char * writeFlags[]    = { "write", nullptr };
            const char * indicateFlags[] = { "indicate", nullptr };
            for (bool write : { true, false })
            {
                GAutoPtr<BluezGattCharacteristic1> characteristic(bluez_gatt_characteristic1_skeleton_new());
                bluez_gatt_characteristic1_set_service(characteristic.get(), "/org/bluez/device/service");
                bluez_gatt_characteristic1_set_uuid(characteristic.get(),
                                                    write ? Ble::CHIP_BLE_CHAR_1_UUID_STR : Ble::CHIP_BLE_CHAR_2_UUID_STR);
                bluez_gatt_characteristic1_set_flags(characteristic.get(), write ? writeFlags : indicateFlags);
                std::unique_ptr<GDBusObject, decltype(&g_object_unref)> object(
                    G_DBUS_OBJECT(
                        bluez_object_skeleton_new(write ? "/org/bluez/device/service/c1" : "/org/bluez/device/service/c2")),
                    g_object_unref);
                bluez_object_skeleton_set_gatt_characteristic1(BLUEZ_OBJECT_SKELETON(object.get()), characteristic.get());
                g_dbus_object_manager_server_export(peer->root.get(), G_DBUS_OBJECT_SKELETON(object.get()));
            }
            g_dbus_object_manager_server_set_connection(peer->root.get(), peer->server.get());
            {
                std::lock_guard<std::mutex> lock(mutex);
                ready = true;
                connected.notify_one();
            }
            g_main_loop_run(serviceLoop);
            g_main_loop_unref(serviceLoop);
            g_main_context_pop_thread_default(context);
            g_main_context_unref(context);
        });
        {
            std::unique_lock<std::mutex> lock(mutex);
            VerifyOrReturnError(connected.wait_for(lock, std::chrono::seconds(5), [this] { return ready; }), CHIP_ERROR_TIMEOUT);
        }
        return DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(
            +[](PrivateBluezGattPeer * peer) {
                GAutoPtr<GError> error;
                peer->objects.reset(bluez_object_manager_client_new_sync(peer->client.get(),
                                                                         G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, nullptr,
                                                                         "/org/bluez", nullptr, &error.GetReceiver()));
                VerifyOrReturnError(peer->objects, CHIP_ERROR_INTERNAL);
                peer->adapter.reset(bluez_adapter1_proxy_new_sync(peer->client.get(), G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
                                                                  nullptr, "/org/bluez/adapter", nullptr, &error.GetReceiver()));
                return peer->adapter ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
            },
            this);
    }
};

struct ScannedDeviceSource
{
    BluezDevice1 * device;
    Ble::ChipBLEDeviceIdentificationInfo info{};
    std::mutex mutex;
    std::condition_variable changed;
    bool returned = false;

    explicit ScannedDeviceSource(BluezDevice1 * scanned) : device(scanned) {}

    void Queue()
    {
        GSource * source = g_idle_source_new();
        g_source_set_callback(
            source,
            [](void * context) -> gboolean {
                auto * scanned = static_cast<ScannedDeviceSource *>(context);
                DeviceLayer::Internal::BLEManagerImplTestAccess::Scanned(DeviceLayer::Internal::BLEMgrImpl(), *scanned->device,
                                                                         scanned->info);
                std::lock_guard<std::mutex> lock(scanned->mutex);
                scanned->returned = true;
                scanned->changed.notify_one();
                return G_SOURCE_REMOVE;
            },
            this, nullptr);
        EXPECT_NE(DeviceLayer::PlatformMgrImpl().GLibMatterContextAttachSource(source), 0u);
        g_source_unref(source);
    }

    bool Wait()
    {
        std::unique_lock<std::mutex> lock(mutex);
        return changed.wait_for(lock, std::chrono::seconds(2), [this] { return returned; });
    }
};

struct GLibConnectBarrier
{
    std::mutex mutex;
    std::condition_variable changed;
    bool entered  = false;
    bool released = false;

    ~GLibConnectBarrier() { Release(); }

    static void Drain()
    {
        GLibConnectBarrier barrier;
        EXPECT_TRUE(barrier.Start());
    }

    bool Start()
    {
        GSource * source = g_idle_source_new();
        g_source_set_callback(
            source,
            [](void * context) -> gboolean {
                auto * barrier = static_cast<GLibConnectBarrier *>(context);
                std::unique_lock<std::mutex> lock(barrier->mutex);
                barrier->entered = true;
                barrier->changed.notify_one();
                barrier->changed.wait(lock, [barrier] { return barrier->released; });
                return G_SOURCE_REMOVE;
            },
            this, nullptr);
        const auto sourceId = DeviceLayer::PlatformMgrImpl().GLibMatterContextAttachSource(source);
        g_source_unref(source);
        std::unique_lock<std::mutex> lock(mutex);
        return sourceId != 0 && changed.wait_for(lock, std::chrono::seconds(2), [this] { return entered; });
    }

    void Release()
    {
        {
            std::lock_guard<std::mutex> lock(mutex);
            released = true;
            changed.notify_one();
        }
        EXPECT_EQ(DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(
                      +[](GLibConnectBarrier *) { return CHIP_NO_ERROR; }, this),
                  CHIP_NO_ERROR);
    }
};

struct BluezConnectionResult
{
    unsigned successes               = 0;
    unsigned errors                  = 0;
    BLE_CONNECTION_OBJECT connection = nullptr;
    CHIP_ERROR error                 = CHIP_NO_ERROR;

    static void Success(void * context, BLE_CONNECTION_OBJECT connection)
    {
        auto & result = *static_cast<BluezConnectionResult *>(context);
        ++result.successes;
        result.connection = connection;
    }

    static void Error(void * context, CHIP_ERROR error)
    {
        auto & result = *static_cast<BluezConnectionResult *>(context);
        ++result.errors;
        result.error = error;
    }
};

class FallbackBle : public Ble::BlePlatformDelegate, public Ble::BleApplicationDelegate, public Ble::BleConnectionDelegate
{
public:
    CHIP_ERROR Install(Ble::BleLayer & layer) { return layer.Init(this, this, this, &DeviceLayer::SystemLayer()); }

    unsigned requests       = 0;
    unsigned cancellations  = 0;
    unsigned invalidUses    = 0;
    CHIP_ERROR cancelResult = CHIP_NO_ERROR;
    std::unique_ptr<DeviceLayer::Internal::BluezConnection> closingConnection;
    SetupDiscriminator discriminator;
    bool active = false;

    void NewConnection(Ble::BleLayer *, void * context, const SetupDiscriminator & requested) override
    {
        EXPECT_FALSE(active);
        ++requests;
        discriminator = requested;
        mContext      = context;
        mSuccess      = OnConnectionComplete;
        mError        = OnConnectionError;
        active        = true;
    }

    void NewConnection(Ble::BleLayer *, void *, BLE_CONNECTION_OBJECT) override { FAIL(); }

    CHIP_ERROR CancelConnection() override
    {
        ++cancellations;
        if (cancelResult == CHIP_NO_ERROR)
        {
            active = false;
        }
        return cancelResult;
    }

    void Complete(Connection & connection)
    {
        ASSERT_TRUE(active);
        active = false;
        mSuccess(mContext, connection.Object());
    }

    void Fail()
    {
        ASSERT_TRUE(active);
        active = false;
        mError(mContext, CHIP_ERROR_TIMEOUT);
    }

private:
    void * mContext                    = nullptr;
    OnConnectionCompleteFunct mSuccess = nullptr;
    OnConnectionErrorFunct mError      = nullptr;

    Connection & Use(BLE_CONNECTION_OBJECT object)
    {
        auto & connection = *reinterpret_cast<Connection *>(object);
        if (connection.retired)
        {
            ++invalidUses;
        }
        return connection;
    }

    void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT) override {}
    CHIP_ERROR SubscribeCharacteristic(BLE_CONNECTION_OBJECT object, const Ble::ChipBleUUID *, const Ble::ChipBleUUID *) override
    {
        Use(object);
        return CHIP_NO_ERROR;
    }
    CHIP_ERROR UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT object, const Ble::ChipBleUUID *, const Ble::ChipBleUUID *) override
    {
        Use(object);
        return CHIP_NO_ERROR;
    }
    CHIP_ERROR CloseConnection(BLE_CONNECTION_OBJECT object) override
    {
        auto & connection = Use(object);
        ++connection.closes;
        connection.retired = true;
        if (closingConnection)
        {
            CHIP_ERROR error = closingConnection->CloseConnection();
            closingConnection.reset();
            return error;
        }
        return CHIP_NO_ERROR;
    }
    uint16_t GetMTU(BLE_CONNECTION_OBJECT) const override { return 200; }
    CHIP_ERROR SendIndication(BLE_CONNECTION_OBJECT, const Ble::ChipBleUUID *, const Ble::ChipBleUUID *,
                              System::PacketBufferHandle) override
    {
        return CHIP_ERROR_NOT_IMPLEMENTED;
    }
    CHIP_ERROR SendWriteRequest(BLE_CONNECTION_OBJECT object, const Ble::ChipBleUUID *, const Ble::ChipBleUUID *,
                                System::PacketBufferHandle) override
    {
        ++Use(object).writes;
        return CHIP_NO_ERROR;
    }
};

class FallbackCredentials : public OperationalCredentialsDelegate
{
    CHIP_ERROR GenerateNOCChain(const ByteSpan &, const ByteSpan &, const ByteSpan &, const ByteSpan &, const ByteSpan &,
                                const ByteSpan &, Callback::Callback<OnNOCChainGeneration> *) override
    {
        return CHIP_ERROR_NOT_IMPLEMENTED;
    }
};

class TestBleFallback : public ::testing::Test
{
public:
    struct State
    {
        TestPersistentStorageDelegate storage;
        Credentials::PersistentStorageOpCertStore certificates;
        Crypto::DefaultSessionKeystore keys;
        Credentials::GroupDataProviderImpl groups;
        FallbackCredentials credentials;
        FallbackBle ble;
        Connection discarded;
        Connection fresh;
        DeviceCommissioner commissioner;
    };

    void SetUp() override
    {
        ASSERT_EQ(Platform::MemoryInit(), CHIP_NO_ERROR);
        state = std::make_unique<State>();
        ASSERT_EQ(state->certificates.Init(&state->storage), CHIP_NO_ERROR);
        state->groups.SetStorageDelegate(&state->storage);
        state->groups.SetSessionKeystore(&state->keys);
        ASSERT_EQ(state->groups.Init(), CHIP_NO_ERROR);
        Credentials::SetGroupDataProvider(&state->groups);
        InitializeFactory();
        auto * layer = DeviceControllerFactory::GetInstance().GetSystemState()->BleLayer();
        layer->Shutdown();
        ASSERT_EQ(state->ble.Install(*layer), CHIP_NO_ERROR);
        Initialize(state->commissioner);
    }

    void InitializeFactory()
    {
        FactoryInitParams factory;
        factory.fabricIndependentStorage = &state->storage;
        factory.opCertStore              = &state->certificates;
        factory.sessionKeystore          = &state->keys;
        factory.groupDataProvider        = &state->groups;
        factory.dataModelProvider        = app::CodegenDataModelProviderInstance(&state->storage);
        ASSERT_EQ(DeviceControllerFactory::GetInstance().Init(factory), CHIP_NO_ERROR);
        DeviceControllerFactory::GetInstance().RetainSystemState();
    }

    void TearDown() override
    {
        state->commissioner.Shutdown();
        EXPECT_EQ(state->ble.invalidUses, 0u);
        if (!factoryStopped)
        {
            DeviceControllerFactory::GetInstance().ReleaseSystemState();
            DeviceControllerFactory::GetInstance().Shutdown();
        }
        Credentials::SetGroupDataProvider(nullptr);
        state->groups.Finish();
        state.reset();
        Platform::MemoryShutdown();
    }

    void Initialize(DeviceCommissioner & commissioner)
    {
        SetupParams setup;
        setup.controllerVendorId             = VendorId::TestVendor1;
        setup.operationalCredentialsDelegate = &state->credentials;
        setup.deviceAttestationVerifier      = Credentials::GetDefaultDACVerifier(nullptr);
        ASSERT_EQ(DeviceControllerFactory::GetInstance().SetupCommissioner(setup, commissioner), CHIP_NO_ERROR);
    }

    RendezvousParameters Parameters()
    {
        RendezvousParameters params;
        SetupDiscriminator discriminator;
        discriminator.SetLongValue(kDiscriminator);
        return params.SetPeerAddress(Transport::PeerAddress::BLE()).SetSetupPINCode(20202021).SetSetupDiscriminator(discriminator);
    }

    void BeginUdp(DeviceCommissioner & commissioner)
    {
        auto & pairer = Testing::DeviceCommissionerTestAccess(&commissioner).GetSetUpCodePairer();
        Testing::SetUpCodePairerTestAccess access(&pairer);
        SetupPayload payload;
        payload.setUpPINCode = 20202021;
        payload.discriminator.SetLongValue(kDiscriminator);
        access.SetSetupPayload(payload);
        access.SetRemoteId(1);
        SetUpCodePairerParameters udp;
        udp.SetPeerAddress(Transport::PeerAddress::UDP(Inet::IPAddress::Any, 5540));
        access.SetCurrentPASEParameters(udp);
        access.ExpectPASEEstablishment();
        Inet::IPAddress loopback;
        ASSERT_TRUE(Inet::IPAddress::FromString("::1", loopback));
        RendezvousParameters parameters;
        parameters.SetPeerAddress(Transport::PeerAddress::UDP(loopback, 9)).SetSetupPINCode(20202021);
        commissioner.RegisterPairingDelegate(&pairer);
        ASSERT_EQ(commissioner.EstablishPASEConnection(1, parameters), CHIP_NO_ERROR);
    }

    void Defer(DeviceCommissioner & commissioner)
    {
        BeginUdp(commissioner);
        auto & pairer = Testing::DeviceCommissionerTestAccess(&commissioner).GetSetUpCodePairer();
        Testing::SetUpCodePairerTestAccess access(&pairer);
        access.CallOnDiscoveredDeviceOverBle(state->discarded.Object(), kDiscriminator);
        EXPECT_EQ(state->discarded.closes, 1u);
        EXPECT_EQ(state->discarded.writes, 0u);
        EXPECT_TRUE(state->discarded.retired);
        EXPECT_EQ(state->ble.requests, 0u);
    }

    CHIP_ERROR StartRequest(DeviceCommissioner & commissioner, NodeId node)
    {
        auto params = Parameters();
        return commissioner.EstablishPASEConnection(node, params);
    }

    void StartFallback(DeviceCommissioner & commissioner)
    {
        Defer(commissioner);
        Testing::DeviceCommissionerTestAccess(&commissioner).FailPASE(CHIP_ERROR_TIMEOUT);
        EXPECT_EQ(state->ble.requests, 1u);
        EXPECT_TRUE(state->ble.active);
        EXPECT_FALSE(state->ble.discriminator.IsShortDiscriminator());
        EXPECT_EQ(state->ble.discriminator.GetLongValue(), kDiscriminator);
    }

    void ExpectPASE(DeviceCommissioner & commissioner, Connection & connection)
    {
        EXPECT_EQ(Testing::DeviceCommissionerTestAccess(&commissioner).GetPASEConnectionObject(), connection.Object());
        EXPECT_GT(connection.writes, 0u);
        EXPECT_EQ(state->discarded.closes, 1u);
        EXPECT_EQ(state->discarded.writes, 0u);
    }

protected:
    std::unique_ptr<State> state;
    bool factoryStopped = false;
};

TEST_F(TestBleFallback, CompleteUdpToFreshBleFallback)
{
    StartFallback(state->commissioner);
    state->ble.Complete(state->fresh);
    ExpectPASE(state->commissioner, state->fresh);
    EXPECT_EQ(state->fresh.closes, 0u);
}

TEST_F(TestBleFallback, DeferredDisconnectDoesNotBlockControllerProgress)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    struct HeldDisconnect
    {
        std::mutex mutex;
        std::condition_variable changed;
        std::unique_ptr<GDBusMessage, decltype(&g_object_unref)> request{ nullptr, g_object_unref };
        unsigned calls             = 0;
        bool progressed            = false;
        bool progressedBeforeReply = false;
    } held;
    const guint filter = g_dbus_connection_add_filter(
        peer.server.get(),
        +[](GDBusConnection *, GDBusMessage * message, gboolean incoming, void * context) -> GDBusMessage * {
            if (incoming && g_dbus_message_get_message_type(message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL &&
                g_strcmp0(g_dbus_message_get_interface(message), "org.bluez.Device1") == 0 &&
                g_strcmp0(g_dbus_message_get_member(message), "Disconnect") == 0)
            {
                auto & pending = *static_cast<HeldDisconnect *>(context);
                std::lock_guard<std::mutex> lock(pending.mutex);
                ++pending.calls;
                pending.request.reset(message);
                pending.changed.notify_one();
                return nullptr;
            }
            return message;
        },
        &held, nullptr);
    GAutoPtr<GError> error;
    GAutoPtr<BluezDevice1> device(bluez_device1_proxy_new_sync(peer.client.get(), G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
                                                               nullptr, "/org/bluez/device", nullptr, &error.GetReceiver()));
    ASSERT_NE(device.get(), nullptr);
    g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(device.get()), 5000);
    state->ble.closingConnection = std::make_unique<BluezConnection>(*device);
    BeginUdp(state->commissioner);
    ASSERT_EQ(SystemLayer().ScheduleLambda([this] {
        auto & pairer = Testing::DeviceCommissionerTestAccess(&state->commissioner).GetSetUpCodePairer();
        Testing::SetUpCodePairerTestAccess(&pairer).CallOnDiscoveredDeviceOverBle(state->discarded.Object(), kDiscriminator);
        EXPECT_EQ(state->discarded.closes, 1u);
        EXPECT_EQ(state->discarded.writes, 0u);
    }),
              CHIP_NO_ERROR);
    ASSERT_EQ(SystemLayer().ScheduleLambda([&held] {
        {
            std::lock_guard<std::mutex> lock(held.mutex);
            held.progressed = true;
            held.changed.notify_one();
        }
        EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR);
    }),
              CHIP_NO_ERROR);
    std::thread reply([&] {
        std::unique_lock<std::mutex> lock(held.mutex);
        if (held.changed.wait_for(lock, std::chrono::seconds(5), [&] { return held.request != nullptr; }))
        {
            held.progressedBeforeReply =
                held.changed.wait_for(lock, std::chrono::milliseconds(500), [&] { return held.progressed; });
            std::unique_ptr<GDBusMessage, decltype(&g_object_unref)> response(
                g_dbus_message_new_method_error_literal(held.request.get(), "org.freedesktop.DBus.Error.UnknownObject",
                                                        "Injected device disappearance"),
                g_object_unref);
            g_dbus_connection_send_message(peer.server.get(), response.get(), G_DBUS_SEND_MESSAGE_FLAGS_NONE, nullptr, nullptr);
        }
    });
    PlatformMgr().RunEventLoop();
    reply.join();
    EXPECT_EQ(held.calls, 1u);
    EXPECT_TRUE(held.progressedBeforeReply);
    g_dbus_connection_remove_filter(peer.server.get(), filter);
}

TEST_F(TestBleFallback, ImmediateBleConnectionReachesPASE)
{
    auto params = Parameters();
    params.SetConnectionObject(state->fresh.Object());
    ASSERT_EQ(state->commissioner.EstablishPASEConnection(1, params), CHIP_NO_ERROR);
    EXPECT_EQ(Testing::DeviceCommissionerTestAccess(&state->commissioner).GetPASEConnectionObject(), state->fresh.Object());
    EXPECT_GT(state->fresh.writes, 0u);
    EXPECT_EQ(state->ble.requests, 0u);
    EXPECT_EQ(state->fresh.closes, 0u);
}

TEST_F(TestBleFallback, StopBeforeFallbackDiscardsCandidate)
{
    Defer(state->commissioner);
    ASSERT_EQ(state->commissioner.StopPairing(1), CHIP_NO_ERROR);
    Testing::SetUpCodePairerTestAccess access(&Testing::DeviceCommissionerTestAccess(&state->commissioner).GetSetUpCodePairer());
    EXPECT_EQ(access.GetDiscoveredParametersCount(), 0u);
    EXPECT_EQ(access.GetRemoteId(), kUndefinedNodeId);
    EXPECT_FALSE(access.GetWaitingForPASE());
    EXPECT_EQ(state->ble.requests, 0u);
}

TEST_F(TestBleFallback, StopDuringFallbackCancelsBackend)
{
    StartFallback(state->commissioner);
    ASSERT_EQ(state->commissioner.StopPairing(1), CHIP_NO_ERROR);
    EXPECT_EQ(state->ble.cancellations, 1u);
    EXPECT_FALSE(state->ble.active);
    EXPECT_EQ(state->fresh.writes, 0u);
}

TEST_F(TestBleFallback, FailedCancellationLateSuccessClosesConnection)
{
    StartFallback(state->commissioner);
    state->ble.cancelResult = CHIP_ERROR_INTERNAL;
    ASSERT_EQ(state->commissioner.StopPairing(1), CHIP_NO_ERROR);
    EXPECT_EQ(state->ble.cancellations, 1u);
    state->ble.Complete(state->fresh);
    EXPECT_EQ(state->fresh.writes, 0u);
    EXPECT_EQ(state->fresh.closes, 1u);
}

TEST_F(TestBleFallback, FailedCancellationLateErrorIsTerminal)
{
    StartFallback(state->commissioner);
    state->ble.cancelResult = CHIP_ERROR_INTERNAL;
    ASSERT_EQ(state->commissioner.StopPairing(1), CHIP_NO_ERROR);
    EXPECT_EQ(state->ble.cancellations, 1u);
    state->ble.Fail();
    EXPECT_EQ(state->ble.requests, 1u);
    EXPECT_EQ(state->fresh.writes, 0u);
    state->ble.cancelResult = CHIP_NO_ERROR;
    ASSERT_EQ(StartRequest(state->commissioner, 2), CHIP_NO_ERROR);
    state->ble.Complete(state->fresh);
    ExpectPASE(state->commissioner, state->fresh);
}

TEST_F(TestBleFallback, SubsequentPairingAfterSuccessfulCancellation)
{
    StartFallback(state->commissioner);
    ASSERT_EQ(state->commissioner.StopPairing(1), CHIP_NO_ERROR);
    ASSERT_EQ(StartRequest(state->commissioner, 2), CHIP_NO_ERROR);
    EXPECT_EQ(state->ble.requests, 2u);
    state->ble.Complete(state->fresh);
    ExpectPASE(state->commissioner, state->fresh);
}

TEST_F(TestBleFallback, FailedCancellationDoesNotReplaceLiveRequest)
{
    StartFallback(state->commissioner);
    state->ble.cancelResult = CHIP_ERROR_INTERNAL;
    ASSERT_EQ(state->commissioner.StopPairing(1), CHIP_NO_ERROR);
    EXPECT_EQ(StartRequest(state->commissioner, 2), CHIP_ERROR_BUSY);
    EXPECT_EQ(state->ble.requests, 1u);
    state->ble.Complete(state->fresh);
    EXPECT_EQ(state->fresh.writes, 0u);
    EXPECT_EQ(state->fresh.closes, 1u);
    state->ble.cancelResult = CHIP_NO_ERROR;
    ASSERT_EQ(StartRequest(state->commissioner, 3), CHIP_NO_ERROR);
    EXPECT_EQ(state->ble.requests, 2u);
    state->ble.Fail();
}

TEST_F(TestBleFallback, OtherCommissionerCannotCancelOwnedFallback)
{
    StartFallback(state->commissioner);
    auto other = std::make_unique<DeviceCommissioner>();
    Initialize(*other);
    EXPECT_EQ(StartRequest(*other, 2), CHIP_ERROR_BUSY);
    other->Shutdown();
    EXPECT_EQ(state->ble.cancellations, 0u);
    state->ble.Complete(state->fresh);
    ExpectPASE(state->commissioner, state->fresh);
}

TEST_F(TestBleFallback, DestroyWithFailedCancellationLateError)
{
    auto owner = std::make_unique<DeviceCommissioner>();
    Initialize(*owner);
    StartFallback(*owner);
    state->ble.cancelResult = CHIP_ERROR_INTERNAL;
    owner->Shutdown();
    owner.reset();
    state->ble.Fail();
    EXPECT_EQ(state->ble.requests, 1u);
}

TEST_F(TestBleFallback, DestroyWithFailedCancellationLateSuccess)
{
    auto owner = std::make_unique<DeviceCommissioner>();
    Initialize(*owner);
    StartFallback(*owner);
    state->ble.cancelResult = CHIP_ERROR_INTERNAL;
    owner->Shutdown();
    owner.reset();
    state->ble.Complete(state->fresh);
    EXPECT_EQ(state->fresh.writes, 0u);
    EXPECT_EQ(state->fresh.closes, 1u);
}

TEST_F(TestBleFallback, LinuxCancelledQueuedScanCannotCompleteReplacement)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    unsigned oldCallbacks = 0;
    unsigned newCallbacks = 0;
    BLEManagerImplTestAccess::Request(BLEMgrImpl(), oldCallbacks);
    ASSERT_EQ(BLEManagerImplTestAccess::Cancel(BLEMgrImpl()), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Request(BLEMgrImpl(), newCallbacks);
    ASSERT_EQ(PlatformMgr().ScheduleWork([](intptr_t) { EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
              CHIP_NO_ERROR);
    PlatformMgr().RunEventLoop();
    EXPECT_EQ(oldCallbacks, 0u);
    EXPECT_EQ(newCallbacks, 1u);
    EXPECT_EQ(BLEManagerImplTestAccess::Cancel(BLEMgrImpl()), CHIP_NO_ERROR);
}

TEST_F(TestBleFallback, LinuxCancelledConnectFailureCannotCompleteReplacement)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    struct HeldConnect
    {
        std::mutex mutex;
        std::condition_variable changed;
        bool called = false;
    } held;
    const guint filter = g_dbus_connection_add_filter(
        peer.server.get(),
        +[](GDBusConnection *, GDBusMessage * message, gboolean incoming, void * context) -> GDBusMessage * {
            if (incoming && g_dbus_message_get_message_type(message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL &&
                g_strcmp0(g_dbus_message_get_interface(message), "org.bluez.Device1") == 0 &&
                g_strcmp0(g_dbus_message_get_member(message), "Connect") == 0)
            {
                auto & pending = *static_cast<HeldConnect *>(context);
                std::lock_guard<std::mutex> lock(pending.mutex);
                pending.called = true;
                pending.changed.notify_one();
                g_object_unref(message);
                return nullptr;
            }
            return message;
        },
        &held, nullptr);
    GAutoPtr<GError> error;
    GAutoPtr<BluezDevice1> device(bluez_device1_proxy_new_sync(peer.client.get(), G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
                                                               nullptr, "/org/bluez/device", nullptr, &error.GetReceiver()));
    ASSERT_NE(device.get(), nullptr);
    g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(device.get()), 5000);
    unsigned oldCallbacks = 0;
    unsigned newCallbacks = 0;
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    auto onError = [](void * context, CHIP_ERROR) { ++*static_cast<unsigned *>(context); };
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &oldCallbacks, nullptr, onError), CHIP_NO_ERROR);
    auto & endpoint          = BLEManagerImplTestAccess::Connecting(BLEMgrImpl());
    CHIP_ERROR connectResult = CHIP_NO_ERROR;
    std::thread connecting([&] { connectResult = endpoint.ConnectDevice(*device); });
    {
        std::unique_lock<std::mutex> lock(held.mutex);
        EXPECT_TRUE(held.changed.wait_for(lock, std::chrono::seconds(5), [&] { return held.called; }));
    }
    GAutoPtr<GCancellable> cancelled(G_CANCELLABLE(g_object_ref(BLEManagerImplTestAccess::ConnectCancellable(endpoint))));
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&oldCallbacks), CHIP_ERROR_BUSY);
    EXPECT_EQ(BLEManagerImplTestAccess::ConnectCancellable(endpoint), cancelled.get());
    EXPECT_TRUE(g_cancellable_is_cancelled(cancelled.get()));
    endpoint.CancelConnect();
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &newCallbacks, nullptr, onError), CHIP_ERROR_BUSY);
    connecting.join();
    EXPECT_EQ(connectResult, CHIP_ERROR_INTERNAL);
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &newCallbacks, nullptr, onError), CHIP_ERROR_BUSY);
    ASSERT_EQ(PlatformMgr().ScheduleWork([](intptr_t) { EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
              CHIP_NO_ERROR);
    PlatformMgr().RunEventLoop();
    EXPECT_EQ(oldCallbacks, 0u);
    EXPECT_EQ(newCallbacks, 0u);
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &newCallbacks, nullptr, onError), CHIP_NO_ERROR);
    {
        std::lock_guard<std::mutex> lock(held.mutex);
        held.called = false;
    }
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl());
    std::thread reconnecting([&] { connectResult = endpoint.ConnectDevice(*device); });
    {
        std::unique_lock<std::mutex> lock(held.mutex);
        EXPECT_TRUE(held.changed.wait_for(lock, std::chrono::seconds(5), [&] { return held.called; }));
    }
    EXPECT_NE(BLEManagerImplTestAccess::ConnectCancellable(endpoint), cancelled.get());
    EXPECT_FALSE(g_cancellable_is_cancelled(BLEManagerImplTestAccess::ConnectCancellable(endpoint)));
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&newCallbacks), CHIP_ERROR_BUSY);
    reconnecting.join();
    EXPECT_EQ(connectResult, CHIP_ERROR_INTERNAL);
    ASSERT_EQ(PlatformMgr().ScheduleWork([](intptr_t) { EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
              CHIP_NO_ERROR);
    PlatformMgr().RunEventLoop();
    EXPECT_EQ(newCallbacks, 0u);
    BLEManagerImplTestAccess::RestorePeripheral(BLEMgrImpl());
    g_dbus_connection_remove_filter(peer.server.get(), filter);
}

TEST_F(TestBleFallback, LinuxCancellationBeforeConnectKeepsPublishedToken)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    const guint filter = g_dbus_connection_add_filter(
        peer.server.get(),
        +[](GDBusConnection * connection, GDBusMessage * message, gboolean incoming, gpointer) -> GDBusMessage * {
            if (incoming && g_dbus_message_get_message_type(message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL &&
                g_strcmp0(g_dbus_message_get_member(message), "Connect") == 0)
            {
                std::unique_ptr<GDBusMessage, decltype(&g_object_unref)> reply(g_dbus_message_new_method_reply(message),
                                                                               g_object_unref);
                g_dbus_connection_send_message(connection, reply.get(), G_DBUS_SEND_MESSAGE_FLAGS_NONE, nullptr, nullptr);
                g_object_unref(message);
                return nullptr;
            }
            return message;
        },
        nullptr, nullptr);
    GAutoPtr<GError> error;
    GAutoPtr<BluezDevice1> device(bluez_device1_proxy_new_sync(peer.client.get(), G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
                                                               nullptr, "/org/bluez/device", nullptr, &error.GetReceiver()));
    ASSERT_NE(device.get(), nullptr);
    g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(device.get()), 1000);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer       = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    unsigned callbacks = 0;
    auto onError       = [](void * context, CHIP_ERROR) { ++*static_cast<unsigned *>(context); };
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
    auto & endpoint = BLEManagerImplTestAccess::Connecting(BLEMgrImpl());
    GAutoPtr<GCancellable> cancelled(G_CANCELLABLE(g_object_ref(BLEManagerImplTestAccess::ConnectCancellable(endpoint))));
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_ERROR_BUSY);
    endpoint.CancelConnect();
    EXPECT_TRUE(g_cancellable_is_cancelled(cancelled.get()));
    EXPECT_EQ(endpoint.ConnectDevice(*device), CHIP_ERROR_INTERNAL);
    EXPECT_EQ(BLEManagerImplTestAccess::ConnectCancellable(endpoint), cancelled.get());
    ASSERT_EQ(PlatformMgr().ScheduleWork([](intptr_t) { EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
              CHIP_NO_ERROR);
    PlatformMgr().RunEventLoop();
    EXPECT_EQ(callbacks, 0u);
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl());
    EXPECT_NE(BLEManagerImplTestAccess::ConnectCancellable(endpoint), cancelled.get());
    EXPECT_FALSE(g_cancellable_is_cancelled(BLEManagerImplTestAccess::ConnectCancellable(endpoint)));
    EXPECT_EQ(endpoint.ConnectDevice(*device), CHIP_NO_ERROR);
    BLEManagerImpl::HandleConnectFailed(CHIP_ERROR_TIMEOUT);
    ASSERT_EQ(PlatformMgr().ScheduleWork([](intptr_t) { EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
              CHIP_NO_ERROR);
    PlatformMgr().RunEventLoop();
    EXPECT_EQ(callbacks, 1u);
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::RestorePeripheral(BLEMgrImpl());
    g_dbus_connection_remove_filter(peer.server.get(), filter);
}

TEST_F(TestBleFallback, LinuxPrivateGattObjectsEnumerated)
{
    PrivateBluezGattPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    GList * objects = g_dbus_object_manager_get_objects(peer.objects.get());
    EXPECT_EQ(g_list_length(objects), 4u);
    g_list_free_full(objects, g_object_unref);
    std::unique_ptr<GDBusObject, decltype(&g_object_unref)> object(
        g_dbus_object_manager_get_object(peer.objects.get(), peer.kDevicePath), g_object_unref);
    ASSERT_NE(object.get(), nullptr);
    GAutoPtr<BluezDevice1> device(bluez_object_get_device1(BLUEZ_OBJECT(object.get())));
    ASSERT_NE(device.get(), nullptr);
    EXPECT_TRUE(bluez_device1_get_connected(device.get()));
    EXPECT_FALSE(bluez_device1_get_services_resolved(device.get()));
}

TEST_F(TestBleFallback, LinuxScannedCallbackReturnsWhileStackLockedAndRejectsOldResults)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezGattPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    ASSERT_EQ(peer.Attach(), CHIP_NO_ERROR);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer       = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    unsigned callbacks = 0;
    auto onError       = [](void * context, CHIP_ERROR) { ++*static_cast<unsigned *>(context); };
    ScannedDeviceSource scanned(peer.proxy.get());
    bool returnedWhileLocked = false;
    {
        StackLock lock;
        ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
        ASSERT_EQ(BLEManagerImplTestAccess::StartScan(BLEMgrImpl(), peer.adapter.get()), CHIP_NO_ERROR);
        ASSERT_TRUE(BLEManagerImplTestAccess::ScannerActive(BLEMgrImpl()));
        scanned.Queue();
        returnedWhileLocked = scanned.Wait();
    }
    EXPECT_TRUE(returnedWhileLocked);
    ASSERT_TRUE(scanned.Wait());
    if (!returnedWhileLocked)
    {
        EXPECT_EQ(PlatformMgrImpl().GLibMatterContextInvokeSync(
                      +[](void *) { return CHIP_NO_ERROR; }, static_cast<void *>(nullptr)),
                  CHIP_NO_ERROR);
        EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_ERROR_BUSY);
        BLEManagerImplTestAccess::ExpireConnect(BLEMgrImpl());
        peer.DrainEvents();
        return;
    }
    {
        StackLock lock;
        EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_NO_ERROR);
        ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
        ASSERT_EQ(BLEManagerImplTestAccess::StartScan(BLEMgrImpl(), peer.adapter.get()), CHIP_NO_ERROR);
    }
    peer.DrainEvents();
    EXPECT_EQ(callbacks, 0u);
    EXPECT_EQ(peer.connects.load(), 0u);
    EXPECT_TRUE(BLEManagerImplTestAccess::ScannerActive(BLEMgrImpl()));
    ScannedDeviceSource mismatch(peer.proxy.get());
    mismatch.info.SetDeviceDiscriminator(kDiscriminator);
    mismatch.Queue();
    ASSERT_TRUE(mismatch.Wait());
    mismatch.info.SetDeviceDiscriminator(0);
    peer.DrainEvents();
    EXPECT_EQ(peer.connects.load(), 0u);
    EXPECT_TRUE(BLEManagerImplTestAccess::ScannerActive(BLEMgrImpl()));
    ScannedDeviceSource match(peer.proxy.get());
    ScannedDeviceSource duplicate(peer.proxy.get());
    match.Queue();
    ASSERT_TRUE(match.Wait());
    duplicate.Queue();
    ASSERT_TRUE(duplicate.Wait());
    match.info.SetDeviceDiscriminator(kDiscriminator);
    duplicate.info.SetDeviceDiscriminator(kDiscriminator);
    peer.DrainEvents();
    GLibConnectBarrier::Drain();
    EXPECT_EQ(peer.connects.load(), 1u);
    EXPECT_EQ(peer.scanStarts.load(), 2u);
    EXPECT_EQ(peer.scanStops.load(), 2u);
    EXPECT_FALSE(BLEManagerImplTestAccess::ScannerActive(BLEMgrImpl()));
    EXPECT_TRUE(BLEManagerImplTestAccess::IsConnecting(BLEMgrImpl()));
    EXPECT_EQ(callbacks, 0u);
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_ERROR_BUSY);
    BLEManagerImplTestAccess::ExpireConnect(BLEMgrImpl());
    peer.DrainEvents();
    EXPECT_EQ(callbacks, 0u);
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_NO_ERROR);
    peer.DrainEvents();
}

TEST_F(TestBleFallback, LinuxQueuedConnectCancellationRetiresPublishedToken)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezGattPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    ASSERT_EQ(peer.Attach(), CHIP_NO_ERROR);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer       = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    unsigned callbacks = 0;
    auto onError       = [](void * context, CHIP_ERROR) { ++*static_cast<unsigned *>(context); };
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Scanning(BLEMgrImpl());
    ScannedDeviceSource scanned(peer.proxy.get());
    scanned.Queue();
    ASSERT_TRUE(scanned.Wait());
    GLibConnectBarrier barrier;
    ASSERT_TRUE(barrier.Start());
    peer.DrainEvents();
    ASSERT_TRUE(BLEManagerImplTestAccess::IsConnecting(BLEMgrImpl()));
    auto & endpoint = *peer.endpoint;
    GAutoPtr<GCancellable> token(G_CANCELLABLE(g_object_ref(BLEManagerImplTestAccess::ConnectCancellable(endpoint))));
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_ERROR_BUSY);
    EXPECT_EQ(BLEManagerImplTestAccess::ConnectCancellable(endpoint), token.get());
    EXPECT_TRUE(g_cancellable_is_cancelled(token.get()));
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_ERROR_BUSY);
    barrier.Release();
    GLibConnectBarrier::Drain();
    peer.DrainEvents();
    EXPECT_EQ(peer.connects.load(), 0u);
    EXPECT_EQ(callbacks, 0u);
    EXPECT_FALSE(BLEManagerImplTestAccess::IsConnecting(BLEMgrImpl()));
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
    void * retiredToken = token.get();
    g_object_add_weak_pointer(G_OBJECT(token.get()), &retiredToken);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl());
    EXPECT_NE(BLEManagerImplTestAccess::ConnectCancellable(endpoint), token.get());
    EXPECT_FALSE(g_cancellable_is_cancelled(BLEManagerImplTestAccess::ConnectCancellable(endpoint)));
    token.reset();
    EXPECT_EQ(retiredToken, nullptr);
    if (retiredToken != nullptr)
    {
        g_object_remove_weak_pointer(G_OBJECT(retiredToken), &retiredToken);
    }
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_ERROR_BUSY);
    BLEManagerImplTestAccess::ExpireConnect(BLEMgrImpl());
    peer.DrainEvents();
}

TEST_F(TestBleFallback, LinuxQueuedWorkerFailureKeepsCapturedRequestId)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezGattPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    ASSERT_EQ(peer.Attach(), CHIP_NO_ERROR);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer          = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    unsigned oldCallbacks = 0;
    unsigned newCallbacks = 0;
    auto onError          = [](void * context, CHIP_ERROR) { ++*static_cast<unsigned *>(context); };
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &oldCallbacks, nullptr, onError), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Scanning(BLEMgrImpl());
    ScannedDeviceSource scanned(peer.proxy.get());
    scanned.Queue();
    ASSERT_TRUE(scanned.Wait());
    GLibConnectBarrier barrier;
    ASSERT_TRUE(barrier.Start());
    peer.DrainEvents();
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&oldCallbacks), CHIP_ERROR_BUSY);
    BLEManagerImplTestAccess::ExpireConnect(BLEMgrImpl());
    peer.DrainEvents();
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &newCallbacks, nullptr, onError), CHIP_NO_ERROR);
    auto & endpoint = BLEManagerImplTestAccess::Connecting(BLEMgrImpl());
    GAutoPtr<GCancellable> replacement(G_CANCELLABLE(g_object_ref(BLEManagerImplTestAccess::ConnectCancellable(endpoint))));
    barrier.Release();
    GLibConnectBarrier::Drain();
    peer.DrainEvents();
    EXPECT_EQ(peer.connects.load(), 0u);
    EXPECT_EQ(oldCallbacks, 0u);
    EXPECT_EQ(newCallbacks, 0u);
    EXPECT_EQ(BLEManagerImplTestAccess::ConnectCancellable(endpoint), replacement.get());
    EXPECT_FALSE(g_cancellable_is_cancelled(replacement.get()));
    EXPECT_TRUE(BLEManagerImplTestAccess::IsConnecting(BLEMgrImpl()));
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &newCallbacks, nullptr, onError), CHIP_ERROR_BUSY);
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&newCallbacks), CHIP_ERROR_BUSY);
    BLEManagerImplTestAccess::ExpireConnect(BLEMgrImpl());
    peer.DrainEvents();
    EXPECT_EQ(newCallbacks, 0u);
}

TEST_F(TestBleFallback, LinuxQueuedSuccessWhileClosingClosesDiscardedLink)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezGattPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    ASSERT_EQ(peer.Attach(), CHIP_NO_ERROR);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer       = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    unsigned callbacks = 0;
    auto onError       = [](void * context, CHIP_ERROR) { ++*static_cast<unsigned *>(context); };
    auto onSuccess     = [](void * context, BLE_CONNECTION_OBJECT) { ++*static_cast<unsigned *>(context); };
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, onSuccess, onError), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl(), peer.proxy.get());
    ASSERT_EQ(peer.SetState(true, true), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(true, true, 1));
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_ERROR_BUSY);
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, onSuccess, onError), CHIP_ERROR_BUSY);
    layer.IndicateBleClosing();
    ASSERT_EQ(PlatformMgr().ScheduleWork([](intptr_t) { EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
              CHIP_NO_ERROR);
    PlatformMgr().RunEventLoop();
    EXPECT_EQ(callbacks, 0u);
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, onSuccess, onError),
              CHIP_ERROR_INCORRECT_STATE);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, onSuccess, onError), CHIP_NO_ERROR);
    EXPECT_EQ(layer.CancelBleIncompleteConnection(&callbacks), CHIP_NO_ERROR);
    EXPECT_TRUE(peer.WaitState(false, true, 0));
    EXPECT_EQ(peer.disconnects.load(), 1u);
    BLEManagerImplTestAccess::RestorePeripheral(BLEMgrImpl());
}

TEST_F(TestBleFallback, LinuxTimedOutConnectClosesLateServicesResolvedAndRetries)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezGattPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    ASSERT_EQ(peer.Attach(), CHIP_NO_ERROR);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    BluezConnectionResult result;
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &result, result.Success, result.Error), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl(), peer.proxy.get());
    BLEManagerImplTestAccess::ExpireConnect(BLEMgrImpl());
    peer.DrainEvents();
    EXPECT_EQ(result.errors, 1u);
    EXPECT_EQ(result.error, CHIP_ERROR_TIMEOUT);
    EXPECT_EQ(result.successes, 0u);

    ASSERT_EQ(peer.SetState(true, true), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(true, true, 1));
    const auto stale = peer.PendingEvent();
    ASSERT_NE(stale.Platform.BLECentralConnected.mPendingTicket, 0u);
    peer.DrainEvents();
    EXPECT_TRUE(peer.WaitState(false, true, 0));
    EXPECT_EQ(peer.disconnects.load(), 1u);
    peer.DrainEvents();
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), stale);
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), stale);
    EXPECT_EQ(result.errors, 1u);
    EXPECT_EQ(result.successes, 0u);

    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &result, result.Success, result.Error), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl(), peer.proxy.get());
    ASSERT_EQ(peer.SetState(true, true), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(true, true, 1));
    const auto fresh = peer.PendingEvent();
    EXPECT_GT(fresh.Platform.BLECentralConnected.mPendingTicket, stale.Platform.BLECentralConnected.mPendingTicket);
    peer.DrainEvents();
    EXPECT_EQ(result.successes, 1u);
    EXPECT_NE(result.connection, nullptr);
    EXPECT_EQ(result.errors, 1u);
    EXPECT_EQ(peer.PendingEvent().Platform.BLECentralConnected.mPendingTicket, 0u);
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), fresh);
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), stale);
    peer.DrainEvents();
    EXPECT_EQ(result.successes, 1u);
    EXPECT_EQ(peer.disconnects.load(), 1u);
    EXPECT_TRUE(bluez_device1_get_connected(peer.proxy.get()));
}

TEST_F(TestBleFallback, LinuxLateServicesResolvedCannotCompleteConnectingReplacement)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezGattPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    ASSERT_EQ(peer.Attach(), CHIP_NO_ERROR);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    BluezConnectionResult original;
    BluezConnectionResult replacement;
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &original, original.Success, original.Error),
              CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl(), peer.proxy.get());
    BLEManagerImplTestAccess::ExpireConnect(BLEMgrImpl());
    peer.DrainEvents();
    ASSERT_EQ(original.errors, 1u);
    PrivateBluezGattPeer nextPeer;
    ASSERT_EQ(nextPeer.Start(), CHIP_NO_ERROR);
    ASSERT_EQ(nextPeer.Attach(), CHIP_NO_ERROR);
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &replacement, replacement.Success, replacement.Error),
              CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl(), nextPeer.proxy.get());
    ASSERT_EQ(peer.SetState(true, true), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(true, true, 1));
    peer.DrainEvents();
    EXPECT_EQ(replacement.successes, 0u);
    EXPECT_EQ(replacement.errors, 0u);
    EXPECT_TRUE(BLEManagerImplTestAccess::IsConnecting(BLEMgrImpl()));
    EXPECT_TRUE(peer.WaitState(false, true, 0));
    EXPECT_EQ(peer.disconnects.load(), 1u);
    ASSERT_EQ(nextPeer.SetState(true, true), CHIP_NO_ERROR);
    ASSERT_TRUE(nextPeer.WaitState(true, true, 1));
    peer.DrainEvents();
    EXPECT_EQ(replacement.successes, 1u);
    EXPECT_EQ(replacement.errors, 0u);
    EXPECT_EQ(nextPeer.disconnects.load(), 0u);
}

TEST_F(TestBleFallback, LinuxDeletedTicketCannotRetireSamePathReplacement)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezGattPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    ASSERT_EQ(peer.Attach(), CHIP_NO_ERROR);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    BluezConnectionResult result;
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &result, result.Success, result.Error), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl(), peer.proxy.get());
    ASSERT_EQ(peer.SetState(true, true), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(true, true, 1));
    auto stale = peer.PendingEvent();
    ASSERT_NE(stale.Platform.BLECentralConnected.mPendingTicket, 0u);
    ASSERT_EQ(peer.SetState(false, false), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(false, false, 0));
    peer.DrainEvents();
    EXPECT_EQ(result.successes, 0u);
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), stale);
    BLEManagerImplTestAccess::ExpireConnect(BLEMgrImpl());
    peer.DrainEvents();
    EXPECT_EQ(result.errors, 1u);

    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &result, result.Success, result.Error), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl(), peer.proxy.get());
    ASSERT_EQ(peer.SetState(true, true), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(true, true, 1));
    const auto fresh = peer.PendingEvent();
    ASSERT_GT(fresh.Platform.BLECentralConnected.mPendingTicket, stale.Platform.BLECentralConnected.mPendingTicket);
    EXPECT_NE(fresh.Platform.BLECentralConnected.mRequestId, stale.Platform.BLECentralConnected.mRequestId);
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), stale);
    EXPECT_EQ(peer.PendingEvent().Platform.BLECentralConnected.mPendingTicket, fresh.Platform.BLECentralConnected.mPendingTicket);
    stale.Platform.BLECentralConnected.mRequestId = fresh.Platform.BLECentralConnected.mRequestId;
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), stale);
    EXPECT_EQ(peer.PendingEvent().Platform.BLECentralConnected.mPendingTicket, fresh.Platform.BLECentralConnected.mPendingTicket);
    EXPECT_EQ(result.successes, 0u);
    EXPECT_EQ(peer.disconnects.load(), 0u);
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), fresh);
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), fresh);
    peer.DrainEvents();
    EXPECT_EQ(result.successes, 1u);
    EXPECT_EQ(result.errors, 1u);
    EXPECT_EQ(peer.disconnects.load(), 0u);
    ASSERT_EQ(peer.SetState(false, false), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(false, false, 0));
    peer.DrainEvents();
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), fresh);
    EXPECT_EQ(result.successes, 1u);
    EXPECT_EQ(peer.disconnects.load(), 0u);
}

TEST_F(TestBleFallback, LinuxRejectedTicketClosesOnlyOnceBeforeDisconnection)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezGattPeer peer;
    peer.disconnectChangesState = false;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    ASSERT_EQ(peer.Attach(), CHIP_NO_ERROR);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    BluezConnectionResult result;
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &result, result.Success, result.Error), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl(), peer.proxy.get());
    BLEManagerImplTestAccess::ExpireConnect(BLEMgrImpl());
    peer.DrainEvents();
    ASSERT_EQ(result.errors, 1u);
    ASSERT_EQ(peer.SetState(true, true), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(true, true, 1));
    const auto pending = peer.PendingEvent();
    peer.DrainEvents();
    EXPECT_TRUE(peer.WaitDisconnects(1));
    EXPECT_EQ(peer.PendingEvent().Platform.BLECentralConnected.mPendingTicket, 0u);
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), pending);
    BLEManagerImplTestAccess::Dispatch(BLEMgrImpl(), pending);
    peer.DrainEvents();
    EXPECT_EQ(peer.disconnects.load(), 1u);
    EXPECT_EQ(result.successes, 0u);
    EXPECT_EQ(result.errors, 1u);
    EXPECT_TRUE(bluez_device1_get_connected(peer.proxy.get()));
    ASSERT_EQ(peer.SetState(false, false), CHIP_NO_ERROR);
    ASSERT_TRUE(peer.WaitState(false, false, 0));
    peer.DrainEvents();
}

TEST_F(TestBleFallback, LinuxStopDiscoveryFailureDoesNotStrandNextPairing)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    PrivateBluezPeer peer;
    ASSERT_EQ(peer.Start(), CHIP_NO_ERROR);
    std::atomic<unsigned> stopCalls{ 0 };
    const guint filter = g_dbus_connection_add_filter(
        peer.server.get(),
        +[](GDBusConnection * connection, GDBusMessage * message, gboolean incoming, void * context) -> GDBusMessage * {
            if (incoming && g_dbus_message_get_message_type(message) == G_DBUS_MESSAGE_TYPE_METHOD_CALL &&
                g_strcmp0(g_dbus_message_get_interface(message), "org.bluez.Adapter1") == 0 &&
                g_strcmp0(g_dbus_message_get_member(message), "StopDiscovery") == 0)
            {
                ++*static_cast<std::atomic<unsigned> *>(context);
                GDBusMessage * reply =
                    g_dbus_message_new_method_error_literal(message, "org.bluez.Error.Failed", "Injected StopDiscovery failure");
                g_dbus_connection_send_message(connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, nullptr, nullptr);
                g_object_unref(reply);
                g_object_unref(message);
                return nullptr;
            }
            return message;
        },
        &stopCalls, nullptr);
    GAutoPtr<GError> error;
    GAutoPtr<BluezAdapter1> adapter(bluez_adapter1_proxy_new_sync(peer.client.get(), G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
                                                                  nullptr, "/org/bluez/adapter", nullptr, &error.GetReceiver()));
    ASSERT_NE(adapter.get(), nullptr);
    g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(adapter.get()), 1000);
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto & layer       = BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    unsigned callbacks = 0;
    auto onError       = [](void * context, CHIP_ERROR) { ++*static_cast<unsigned *>(context); };
    ASSERT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::InstallScanningAdapter(BLEMgrImpl(), adapter.get());
    EXPECT_EQ(layer.CancelBleIncompleteConnection(), CHIP_NO_ERROR);
    EXPECT_EQ(stopCalls.load(), 1u);
    EXPECT_FALSE(BLEManagerImplTestAccess::ScannerActive(BLEMgrImpl()));
    EXPECT_EQ(layer.NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
    EXPECT_EQ(layer.CancelBleIncompleteConnection(), CHIP_NO_ERROR);
    ASSERT_EQ(PlatformMgr().ScheduleWork([](intptr_t) { EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
              CHIP_NO_ERROR);
    PlatformMgr().RunEventLoop();
    EXPECT_EQ(callbacks, 0u);
    g_dbus_connection_remove_filter(peer.server.get(), filter);
}

TEST_F(TestBleFallback, LinuxFactoryShutdownWithQueuedCancelledCompletion)
{
    using namespace DeviceLayer;
    using namespace DeviceLayer::Internal;
    ASSERT_EQ(BLEManagerImplTestAccess::InstallBackend(BLEMgrImpl()), CHIP_NO_ERROR);
    auto * layer       = &BLEManagerImplTestAccess::Layer(BLEMgrImpl());
    unsigned callbacks = 0;
    auto onError       = [](void * context, CHIP_ERROR) { ++*static_cast<unsigned *>(context); };
    ASSERT_EQ(layer->NewBleConnectionByDiscriminator(SetupDiscriminator(), &callbacks, nullptr, onError), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl());
    BLEManagerImpl::HandleConnectFailed(CHIP_ERROR_INTERNAL);
    EXPECT_EQ(layer->CancelBleIncompleteConnection(&callbacks), CHIP_ERROR_BUSY);
    state->commissioner.Shutdown();
    DeviceControllerFactory::GetInstance().ReleaseSystemState();
    DeviceControllerFactory::GetInstance().Shutdown();
    factoryStopped = true;
    EXPECT_EQ(layer, &BLEManagerImplTestAccess::Layer(BLEMgrImpl()));
    EXPECT_EQ(callbacks, 0u);
    BLEManagerImplTestAccess::RestorePeripheral(BLEMgrImpl());
    InitializeFactory();
    factoryStopped = false;
    Initialize(state->commissioner);
    unsigned newCallbacks = 0;
    EXPECT_EQ(layer->NewBleConnectionByDiscriminator(SetupDiscriminator(), &newCallbacks, nullptr, onError), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::Connecting(BLEMgrImpl());
    ASSERT_EQ(PlatformMgr().ScheduleWork([](intptr_t) { EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
              CHIP_NO_ERROR);
    PlatformMgr().RunEventLoop();
    EXPECT_EQ(callbacks, 0u);
    EXPECT_EQ(newCallbacks, 0u);
    EXPECT_EQ(layer->NewBleConnectionByDiscriminator(SetupDiscriminator(), &newCallbacks, nullptr, onError), CHIP_ERROR_BUSY);
    BLEManagerImpl::HandleConnectFailed(CHIP_ERROR_TIMEOUT);
    ASSERT_EQ(PlatformMgr().ScheduleWork([](intptr_t) { EXPECT_EQ(PlatformMgr().StopEventLoopTask(), CHIP_NO_ERROR); }),
              CHIP_NO_ERROR);
    PlatformMgr().RunEventLoop();
    EXPECT_EQ(newCallbacks, 1u);
    EXPECT_EQ(layer->NewBleConnectionByDiscriminator(SetupDiscriminator(), &newCallbacks, nullptr, onError), CHIP_NO_ERROR);
    EXPECT_EQ(layer->CancelBleIncompleteConnection(&newCallbacks), CHIP_NO_ERROR);
    BLEManagerImplTestAccess::RestorePeripheral(BLEMgrImpl());
}

} // namespace
#else
TEST(TestBleFallback, BleTransportDisabled)
{
    EXPECT_FALSE(CONFIG_NETWORK_LAYER_BLE && CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE);
}
#endif
