package ch.threema.app.apptaskexecutor

import ch.threema.app.apptaskexecutor.tasks.RemoteSecretDeleteStepsTask
import ch.threema.storage.factories.AppTaskPersistenceFactory
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
import kotlinx.coroutines.test.runTest

class DatabaseAppTaskPersistenceTest {

    private val validEncodedAppTaskData =
        "{\"type\":\"ch.threema.app.apptaskexecutor.tasks.RemoteSecretDeleteStepsTask.RemoteSecretDeleteStepsTaskData\"," +
            "\"authenticationToken\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]}"

    @Test
    fun `inserting tasks that cannot be serialized should not throw an exception`() = runTest {
        val appTaskPersistenceFactoryMock = mockk<AppTaskPersistenceFactory>()

        val databaseAppTaskPersistence = DatabaseAppTaskPersistence(appTaskPersistenceFactoryMock)

        databaseAppTaskPersistence.persistTask(mockk())

        verify(exactly = 0) { appTaskPersistenceFactoryMock.insert(any()) }
    }

    @Test
    fun `removing tasks that cannot be serialized should not throw an exception`() = runTest {
        val appTaskPersistenceFactoryMock = mockk<AppTaskPersistenceFactory>()

        val databaseAppTaskPersistence = DatabaseAppTaskPersistence(appTaskPersistenceFactoryMock)

        databaseAppTaskPersistence.removePersistedTask(mockk())

        verify(exactly = 0) { appTaskPersistenceFactoryMock.removeAll(any()) }
    }

    @Test
    fun `persisted tasks that fail to decode should just be skipped`() = runTest {
        val appTaskPersistenceFactoryMock = mockk<AppTaskPersistenceFactory>()
        every { appTaskPersistenceFactoryMock.getAll() } returns setOf(
            validEncodedAppTaskData,
            "this encoded task cannot be decoded :)",
        )

        val databaseAppTaskPersistence = DatabaseAppTaskPersistence(appTaskPersistenceFactoryMock)
        val persistedTasks = databaseAppTaskPersistence.loadAllPersistedTasks()
        assertEquals(1, persistedTasks.size)
        assertIs<RemoteSecretDeleteStepsTask>(persistedTasks.first())
    }
}
