package coredevices import cocoapods.FirebaseCore.FIRConfiguration import cocoapods.FirebaseCore.FIRLoggerLevelDebug import coredevices.firestore.PebbleUser import coredevices.firestore.User import coredevices.firestore.UsersDao import coredevices.mcp.client.McpSession import coredevices.ring.agent.BuiltinServletRepository import coredevices.ring.agent.builtin_servlets.notes.NoteProvider import coredevices.ring.agent.builtin_servlets.reminders.ReminderProvider import coredevices.ring.data.NoteShortcutType import coredevices.ring.database.MusicControlMode import coredevices.ring.agent.builtin_servlets.messaging.ApprovedBeeperContact import coredevices.ring.database.Preferences import coredevices.ring.database.SecondaryMode import coredevices.ring.firestoreModule import coredevices.ring.mcpModule import coredevices.util.Platform import coredevices.util.models.CactusSTTMode import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.auth.FirebaseAuthException import dev.gitlive.firebase.auth.auth import dev.gitlive.firebase.initialize import io.ktor.client.HttpClient import io.ktor.client.engine.HttpClientEngine import kotlinx.cinterop.toKString import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import org.koin.core.context.startKoin import org.koin.dsl.bind import org.koin.dsl.module import org.koin.mp.KoinPlatform import platform.posix.getenv object TestUtil { private val loginDefer = CompletableDeferred() private suspend fun initAuth() { FIRConfiguration.sharedInstance.setLoggerLevel(FIRLoggerLevelDebug) val token = getenv("TESTS_FB_CUSTOM_TOKEN")?.toKString() ?: error("TESTS_FB_CUSTOM_TOKEN env var not set") try { Firebase.auth.signInWithCustomToken(token).user ?: error("Couldn't sign in") loginDefer.complete(Unit) } catch (e: Exception) { loginDefer.completeExceptionally(e) } } @Throws(IllegalStateException::class, FirebaseAuthException::class) suspend fun waitForAuth() { loginDefer.await() } suspend fun initTestApp() { val koin = startKoin { allowOverride(true) modules( module { factory { HttpClient().engine } bind HttpClientEngine::class }, firestoreModule, experimentalModule, mcpModule, module { single { PreferencesTestImpl } bind Preferences::class single { object : Platform { override val name: String get() = "iOS" override val deviceModelName: String get() = "Test Device" override suspend fun openUrl(url: String) { } override suspend fun runWithBgTask( name: String, task: suspend () -> Unit ) { task() } } } bind Platform::class single { UsersDaoTestImpl } bind UsersDao::class } ) } Firebase.initialize(null) initAuth() } fun getTestableMcpSession(): McpSession { val koin = KoinPlatform.getKoin() val builtinMcpRepository: BuiltinServletRepository = koin.get() val scope = CoroutineScope(Dispatchers.Default) val mcpIntegrations = builtinMcpRepository.getAllServlets().map { builtinMcpRepository.resolveName(it.name)!! } return McpSession( integrations = mcpIntegrations, scope = scope ) } } private object PreferencesTestImpl: Preferences { override val useCactusAgent: StateFlow get() = MutableStateFlow(false) override val useCactusTranscription: StateFlow get() = TODO("Not yet implemented") override val cactusMode: CactusSTTMode get() = TODO("Not yet implemented") override val ringPaired: StateFlow get() = TODO("Not yet implemented") override val ringPairedName: StateFlow get() = TODO("Not yet implemented") override val ringPairedOld: StateFlow get() = TODO("Not yet implemented") override val musicControlMode: StateFlow get() = TODO("Not yet implemented") override val lastSyncIndex: StateFlow get() = TODO("Not yet implemented") override val debugDetailsEnabled: StateFlow get() = TODO("Not yet implemented") override val approvedBeeperContacts: StateFlow> get() = TODO("Not yet implemented") override val secondaryMode: StateFlow get() = TODO("Not yet implemented") override val reminderProvider: StateFlow get() = TODO("Not yet implemented") override val noteProvider: StateFlow get() = TODO("Not yet implemented") override val noteShortcut: StateFlow get() = TODO("Not yet implemented") override val backupEnabled: StateFlow get() = MutableStateFlow(true) override val useEncryption: StateFlow get() = MutableStateFlow(false) override val encryptionKeyFingerprint: StateFlow get() = MutableStateFlow(null) override val lastWipedRing: StateFlow get() = MutableStateFlow(null) override val lastBackupCount: StateFlow get() = MutableStateFlow(null) override suspend fun setUseCactusAgent(useCactus: Boolean) { TODO("Not yet implemented") } override suspend fun setUseCactusTranscription(useCactus: Boolean) { TODO("Not yet implemented") } override fun setCactusMode(mode: CactusSTTMode) { TODO("Not yet implemented") } override fun setRingPaired(id: String?) { TODO("Not yet implemented") } override fun setRingPairedName(name: String?) { TODO("Not yet implemented") } override fun setMusicControlMode(mode: MusicControlMode) { TODO("Not yet implemented") } override suspend fun setLastSyncIndex(index: Int?) { TODO("Not yet implemented") } override fun setDebugDetailsEnabled(enabled: Boolean) { TODO("Not yet implemented") } override suspend fun setApprovedBeeperContacts(contacts: List?) { TODO("Not yet implemented") } override fun setSecondaryMode(mode: SecondaryMode) { TODO("Not yet implemented") } override fun setReminderProvider(provider: ReminderProvider) { TODO("Not yet implemented") } override fun setNoteProvider(provider: NoteProvider) { TODO("Not yet implemented") } override fun setNoteShortcut(shortcut: NoteShortcutType) { TODO("Not yet implemented") } override fun setBackupEnabled(enabled: Boolean) {} override fun setUseEncryption(enabled: Boolean) {} override fun setEncryptionKeyFingerprint(fingerprint: String?) {} override fun setLastWipedRing(id: String?) {} override fun setLastBackupCount(count: Int?) {} } private object UsersDaoTestImpl: UsersDao { override val user: Flow = MutableStateFlow(PebbleUser(false, User())) override val loginEvents: Flow get() = TODO("Not yet implemented") override suspend fun updateTodoBlockId(todoBlockId: String) { } override suspend fun initUserDevToken(rebbleUserToken: String?) { } override suspend fun updateLastConnectedWatch(serial: String) { } override suspend fun updateRingLifetimeCollectionCount( serial: String, count: Int ) { } override fun init() { TODO("Not yet implemented") } }