/*
 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package kotlinx.coroutines.android

import android.os.*
import kotlinx.coroutines.*
import org.junit.Test
import org.junit.runner.*
import org.robolectric.*
import org.robolectric.Shadows.*
import org.robolectric.annotation.*
import org.robolectric.shadows.*
import org.robolectric.util.*
import kotlin.test.*

@RunWith(RobolectricTestRunner::class)
@Config(manifest = Config.NONE, sdk = [28])
class HandlerDispatcherTest : TestBase() {

    /**
     * Because [Dispatchers.Main] is a singleton, we cannot vary its initialization behavior. As a
     * result we only test its behavior on the newest API level and assert that it uses async
     * messages. We rely on the other tests to exercise the variance of the mechanism that the main
     * dispatcher uses to ensure it has correct behavior on all API levels.
     */
    @Test
    fun mainIsAsync() = runTest {
        ReflectionHelpers.setStaticField(Build.VERSION::class.java, "SDK_INT", 28)

        val mainLooper = ShadowLooper.getShadowMainLooper()
        mainLooper.pause()
        val mainMessageQueue = shadowOf(Looper.getMainLooper().queue)

        val job = launch(Dispatchers.Main) {
            expect(2)
        }

        val message = mainMessageQueue.head
        assertTrue(message.isAsynchronous)
        job.join(mainLooper)
    }

    @Test
    fun asyncMessagesApi14() = runTest {
        ReflectionHelpers.setStaticField(Build.VERSION::class.java, "SDK_INT", 14)

        val main = Looper.getMainLooper().asHandler(async = true).asCoroutineDispatcher()

        val mainLooper = ShadowLooper.getShadowMainLooper()
        mainLooper.pause()
        val mainMessageQueue = shadowOf(Looper.getMainLooper().queue)

        val job = launch(main) {
            expect(2)
        }

        val message = mainMessageQueue.head
        assertFalse(message.isAsynchronous)
        job.join(mainLooper)
    }

    @Test
    fun asyncMessagesApi16() = runTest {
        ReflectionHelpers.setStaticField(Build.VERSION::class.java, "SDK_INT", 16)

        val main = Looper.getMainLooper().asHandler(async = true).asCoroutineDispatcher()

        val mainLooper = ShadowLooper.getShadowMainLooper()
        mainLooper.pause()
        val mainMessageQueue = shadowOf(Looper.getMainLooper().queue)

        val job = launch(main) {
            expect(2)
        }

        val message = mainMessageQueue.head
        assertTrue(message.isAsynchronous)
        job.join(mainLooper)
    }

    @Test
    fun asyncMessagesApi28() = runTest {
        ReflectionHelpers.setStaticField(Build.VERSION::class.java, "SDK_INT", 28)

        val main = Looper.getMainLooper().asHandler(async = true).asCoroutineDispatcher()

        val mainLooper = ShadowLooper.getShadowMainLooper()
        mainLooper.pause()
        val mainMessageQueue = shadowOf(Looper.getMainLooper().queue)

        val job = launch(main) {
            expect(2)
        }

        val message = mainMessageQueue.head
        assertTrue(message.isAsynchronous)
        job.join(mainLooper)
    }

    @Test
    fun noAsyncMessagesIfNotRequested() = runTest {
        ReflectionHelpers.setStaticField(Build.VERSION::class.java, "SDK_INT", 28)

        val main = Looper.getMainLooper().asHandler(async = false).asCoroutineDispatcher()

        val mainLooper = ShadowLooper.getShadowMainLooper()
        mainLooper.pause()
        val mainMessageQueue = shadowOf(Looper.getMainLooper().queue)

        val job = launch(main) {
            expect(2)
        }

        val message = mainMessageQueue.head
        assertFalse(message.isAsynchronous)
        job.join(mainLooper)
    }

    @Test
    fun testToString() {
        ReflectionHelpers.setStaticField(Build.VERSION::class.java, "SDK_INT", 28)
        val main = Looper.getMainLooper().asHandler(async = true).asCoroutineDispatcher("testName")
        assertEquals("testName", main.toString())
        assertEquals("testName [immediate]", main.immediate.toString())
        assertEquals("testName [immediate]", main.immediate.immediate.toString())
    }

    private suspend fun Job.join(mainLooper: ShadowLooper) {
        expect(1)
        mainLooper.unPause()
        join()
        finish(3)
    }

    // TODO compile against API 23+ so this can be invoked without reflection.
    private val Looper.queue: MessageQueue
        get() = Looper::class.java.getDeclaredMethod("getQueue").invoke(this) as MessageQueue

    // TODO compile against API 22+ so this can be invoked without reflection.
    private val Message.isAsynchronous: Boolean
        get() = Message::class.java.getDeclaredMethod("isAsynchronous").invoke(this) as Boolean

    @Test
    fun testImmediateDispatcherYield() = runBlocking(Dispatchers.Main) {
        expect(1)
        // launch in the immediate dispatcher
        launch(Dispatchers.Main.immediate) {
            expect(2)
            yield()
            expect(4)
        }
        expect(3) // after yield
        yield() // yield back
        finish(5)
    }
}
