package fdroidbuildstatus.adapter.gitlab

import de.storchp.fdroidbuildstatus.adapter.ApiResponse
import de.storchp.fdroidbuildstatus.adapter.gitlab.GitlabClient
import de.storchp.fdroidbuildstatus.adapter.gitlab.Metadata
import fdroidbuildstatus.utils.TestUtils
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.assertj.core.api.Assertions
import org.awaitility.Awaitility
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference

internal class GitlabClientTest {
    private var server: MockWebServer? = null
    private var client: GitlabClient? = null

    @BeforeEach
    fun setUp() {
        server = MockWebServer()
        server!!.start()
        val baseUrl = server!!.url("/")
        client = GitlabClient(baseUrl.toString())
    }

    @AfterEach
    fun teardown() {
        server!!.shutdown()
    }

    @Test
    fun callGetFdroidDataMetadata() {
        server!!.enqueue(MockResponse().setBody(TestUtils.fromFile("my.app.id.yml")))
        val response = AtomicReference<ApiResponse<Metadata?>>()
        client!!.getFdroidDataMetadata("my.app.id")
        { apiResponse: ApiResponse<Metadata?> -> response.set(apiResponse) }
        Awaitility.await().atMost(1, TimeUnit.SECONDS).until { response.get() != null }
        Assertions.assertThat(server!!.takeRequest().path)
            .isEqualTo("/fdroid/fdroiddata/-/raw/master/metadata/my.app.id.yml")
        Assertions.assertThat(
            response.get()!!.value()
        ).isEqualTo(
            Metadata(
                sourceCode = "https://example.com/maxmuster/MyApp",
                autoName = "My App",
                builds = setOf(
                    Metadata.Build(1, "1.0"),
                    Metadata.Build(2, "1.1")
                )
            )
        )
    }

    @Test
    fun callGetFdroidDataMetadataNotFound() {
        server!!.enqueue(MockResponse().setResponseCode(404))
        val response = AtomicReference<ApiResponse<Metadata?>>()
        client!!.getFdroidDataMetadata("my.app.id")
        { apiResponse: ApiResponse<Metadata?> -> response.set(apiResponse) }
        Awaitility.await().atMost(1, TimeUnit.SECONDS).until { response.get() != null }
        Assertions.assertThat(server!!.takeRequest().path)
            .isEqualTo("/fdroid/fdroiddata/-/raw/master/metadata/my.app.id.yml")
        Assertions.assertThat(
            response.get()!!.status()
        ).isEqualTo(ApiResponse.Status.NOT_FOUND)
        Assertions.assertThat(
            response.get()!!.value()
        ).isNull()
    }
}