package com.github.nullptroma.wallenc.domain.vault.network.yandexdisk.repository

import com.github.nullptroma.wallenc.domain.vault.network.yandexdisk.YandexDiskAuthException
import com.github.nullptroma.wallenc.domain.vault.network.yandexdisk.YandexDiskRepositoryTestFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import okhttp3.OkHttpClient
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test

class YandexDiskRepositoryTest {

    private lateinit var server: MockWebServer
    private lateinit var repository: YandexDiskRepository

    @Before
    fun setUp() {
        server = MockWebServer()
        server.start()
        val api = YandexDiskRepositoryTestFactory.createApi(server.url("/").toString()) { "test-token" }
        repository = YandexDiskRepository(api, OkHttpClient(), Dispatchers.IO)
    }

    @After
    fun tearDown() {
        server.shutdown()
    }

    @Test
    fun diskInfoParsesResponse() = runBlocking {
        repository.resetCloudApiCallCount()
        server.enqueue(
            MockResponse()
                .setResponseCode(200)
                .setBody("""{"total_space":1000,"used_space":200,"trash_size":0}""")
                .addHeader("Content-Type", "application/json"),
        )
        val info = repository.diskInfo()
        assertEquals(1000L, info.totalSpace)
        assertEquals(200L, info.usedSpace)
        assertEquals(1L, repository.cloudApiCallCount())
    }

    @Test
    fun listReturnsEmptyEmbeddedOn404() = runBlocking {
        repeat(2) {
            server.enqueue(MockResponse().setResponseCode(404))
        }
        val result = repository.list("disk:/missing", limit = 10, offset = 0)
        assertTrue(result.embedded?.items?.isEmpty() == true)
    }

    @Test
    fun diskInfoThrowsAuthExceptionOn401() = runBlocking {
        server.enqueue(MockResponse().setResponseCode(401))
        try {
            repository.diskInfo()
            error("Expected YandexDiskAuthException")
        } catch (_: YandexDiskAuthException) {
            // expected
        }
    }
}
