package com.syncflow

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import com.syncflow.data.providers.webdav.WebDavProvider
import com.syncflow.domain.model.CloudAccount
import com.syncflow.domain.model.ProviderType
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Assume.assumeTrue
import org.junit.Test
import org.junit.runner.RunWith
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream

/**
 * Live test of the app's SFTPGo provider (which is WebDavProvider) against a real SFTPGo
 * server over its externally-exposed WebDAV URL. Validates the provider against a different
 * WebDAV implementation than Nextcloud. Creds via -e davUrl/davUser/davPass; skips otherwise.
 */
@RunWith(AndroidJUnit4::class)
class SftpgoWebDavTest {

    private val args = InstrumentationRegistry.getArguments()

    private fun provider() = WebDavProvider(
        CloudAccount(
            id = 1, displayName = "sftpgo", email = null, providerType = ProviderType.SFTPGO,
            credentialJson = """{"username":"${args.getString("davUser")}","password":"${args.getString("davPass")}"}""",
            serverUrl = args.getString("davUrl"), port = null,
        ),
    )

    @Test fun sftpgoWebDavRoundTrip() = runBlocking {
        assumeTrue("davUrl/davUser/davPass required", args.getString("davUrl") != null)
        val p = provider()
        val dir = "SyncFlowDav_${System.currentTimeMillis()}"
        try {
            assertTrue("testConnection", p.testConnection().isSuccess)
            assertTrue("mkdir", p.createDirectory(dir).isSuccess)

            // upload (atomic temp + MOVE), list, download — with a non-ASCII payload
            val body = "sftpgo webdav round-trip ✓ café".toByteArray()
            assertTrue("upload", p.uploadFile(ByteArrayInputStream(body), "$dir/f.txt", body.size.toLong()).isSuccess)
            assertTrue("f.txt" in p.listFiles(dir).getOrThrow().map { it.name })
            val out = ByteArrayOutputStream(); p.downloadFile("$dir/f.txt", out).getOrThrow()
            assertEquals("sftpgo webdav round-trip ✓ café", out.toString("UTF-8"))

            // overwrite via atomic temp+MOVE
            val v2 = "updated-content".toByteArray()
            assertTrue(p.uploadFile(ByteArrayInputStream(v2), "$dir/f.txt", v2.size.toLong()).isSuccess)
            val out2 = ByteArrayOutputStream(); p.downloadFile("$dir/f.txt", out2).getOrThrow()
            assertEquals("updated-content", out2.toString("UTF-8"))

            // non-ASCII / special filename (the URL/MOVE-header encoding fix)
            val special = "café & rapport (1).txt"
            assertTrue(p.uploadFile(ByteArrayInputStream("x".toByteArray()), "$dir/$special", 1).isSuccess)
            assertTrue(special in p.listFiles(dir).getOrThrow().map { it.name })

            // delete
            assertTrue(p.deleteFile("$dir/f.txt").isSuccess)
            assertTrue("f.txt" !in p.listFiles(dir).getOrThrow().map { it.name })
        } finally {
            runCatching { p.deleteFile(dir) }
        }
    }
}
