package ru.forbion.f7cloud.core.network

import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertTrue
import org.junit.Test

/**
 * Тесты подписи коллекций CardDAV (CTag/sync-token) — основа инкрементальной
 * синхронизации: если подпись не изменилась, контакты не перекачиваются.
 */
class CardDavSignatureTest {

    private val ns = """xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/""""

    private fun body(vararg responses: String) =
        """<?xml version="1.0"?><d:multistatus $ns>${responses.joinToString("")}</d:multistatus>"""

    private fun resp(href: String, ctag: String? = null, token: String? = null) = """
        <d:response>
          <d:href>$href</d:href>
          <d:propstat><d:prop>
            ${ctag?.let { "<cs:getctag>$it</cs:getctag>" } ?: ""}
            ${token?.let { "<d:sync-token>$it</d:sync-token>" } ?: ""}
          </d:prop></d:propstat>
        </d:response>
    """.trimIndent()

    @Test fun ctag_signature_is_stable_and_sorted() {
        val a = CardDavClient.parseCollectionSignature(
            body(resp("/dav/addressbooks/u/b1/", ctag = "111"), resp("/dav/addressbooks/u/b2/", ctag = "222")),
        )
        // порядок ответов не влияет на подпись
        val b = CardDavClient.parseCollectionSignature(
            body(resp("/dav/addressbooks/u/b2/", ctag = "222"), resp("/dav/addressbooks/u/b1/", ctag = "111")),
        )
        assertEquals(a, b)
        assertTrue(a.contains("/dav/addressbooks/u/b1/=111"))
        assertTrue(a.contains("/dav/addressbooks/u/b2/=222"))
    }

    @Test fun ctag_change_changes_signature() {
        val before = CardDavClient.parseCollectionSignature(body(resp("/b1/", ctag = "111")))
        val after = CardDavClient.parseCollectionSignature(body(resp("/b1/", ctag = "999")))
        assertNotEquals(before, after)
    }

    @Test fun sync_token_fallback_when_no_ctag() {
        val sig = CardDavClient.parseCollectionSignature(body(resp("/b1/", token = "http://sabre/sync/42")))
        assertEquals("/b1/=http://sabre/sync/42", sig)
    }

    @Test fun empty_when_no_tags() {
        assertEquals("", CardDavClient.parseCollectionSignature(body(resp("/b1/"))))
    }
}
