/*
 * Copyright 2016-2017 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

@file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913

package kotlinx.coroutines.experimental

import kotlin.coroutines.experimental.*
import kotlin.test.*

class CompletableDeferredTest : TestBase() {
    @Test
    fun testFresh() {
        val c = CompletableDeferred<String>()
        checkFresh(c)
    }

    private fun checkFresh(c: CompletableDeferred<String>) {
        assertEquals(true, c.isActive)
        assertEquals(false, c.isCancelled)
        assertEquals(false, c.isCompleted)
        assertEquals(false, c.isCompletedExceptionally)
        assertThrows<IllegalStateException> { c.getCancellationException() }
        assertThrows<IllegalStateException> { c.getCompleted() }
        assertThrows<IllegalStateException> { c.getCompletionExceptionOrNull() }
    }

    @Test
    fun testComplete() {
        val c = CompletableDeferred<String>()
        assertEquals(true, c.complete("OK"))
        checkCompleteOk(c)
        assertEquals(false, c.complete("OK"))
        checkCompleteOk(c)
    }

    private fun checkCompleteOk(c: CompletableDeferred<String>) {
        assertEquals(false, c.isActive)
        assertEquals(false, c.isCancelled)
        assertEquals(true, c.isCompleted)
        assertEquals(false, c.isCompletedExceptionally)
        assertTrue(c.getCancellationException() is JobCancellationException)
        assertEquals("OK", c.getCompleted())
        assertEquals(null, c.getCompletionExceptionOrNull())
    }

    @Test
    fun testCompleteWithException() {
        val c = CompletableDeferred<String>()
        assertEquals(true, c.completeExceptionally(TestException()))
        checkCompleteTestException(c)
        assertEquals(false, c.completeExceptionally(TestException()))
        checkCompleteTestException(c)
    }

    private fun checkCompleteTestException(c: CompletableDeferred<String>) {
        assertEquals(false, c.isActive)
        assertEquals(false, c.isCancelled)
        assertEquals(true, c.isCompleted)
        assertEquals(true, c.isCompletedExceptionally)
        assertTrue(c.getCancellationException() is JobCancellationException)
        assertThrows<TestException> { c.getCompleted() }
        assertTrue(c.getCompletionExceptionOrNull() is TestException)
    }

    @Test
    fun testCancel() {
        val c = CompletableDeferred<String>()
        assertEquals(true, c.cancel())
        checkCancel(c)
        assertEquals(false, c.cancel())
        checkCancel(c)
    }

    private fun checkCancel(c: CompletableDeferred<String>) {
        assertEquals(false, c.isActive)
        assertEquals(true, c.isCancelled)
        assertEquals(true, c.isCompleted)
        assertEquals(true, c.isCompletedExceptionally)
        assertThrows<CancellationException> { c.getCompleted() }
        assertTrue(c.getCompletionExceptionOrNull() is CancellationException)
    }

    @Test
    fun testCancelWithException() {
        val c = CompletableDeferred<String>()
        assertEquals(true, c.cancel(TestException()))
        checkCancelWithException(c)
        assertEquals(false, c.cancel(TestException()))
        checkCancelWithException(c)
    }

    private fun checkCancelWithException(c: CompletableDeferred<String>) {
        assertEquals(false, c.isActive)
        assertEquals(true, c.isCancelled)
        assertEquals(true, c.isCompleted)
        assertEquals(true, c.isCompletedExceptionally)
        assertTrue(c.getCancellationException() is JobCancellationException)
        assertThrows<TestException> { c.getCompleted() }
        assertTrue(c.getCompletionExceptionOrNull() is TestException)
    }

    @Test
    fun testParentCancelsChild() {
        val parent = Job()
        val c = CompletableDeferred<String>(parent)
        checkFresh(c)
        parent.cancel()
        assertEquals(false, parent.isActive)
        assertEquals(true, parent.isCancelled)
        checkCancel(c)
    }

    @Test
    fun testParentActiveOnChildCompletion() {
        val parent = Job()
        val c = CompletableDeferred<String>(parent)
        checkFresh(c)
        assertEquals(true, parent.isActive)
        assertEquals(true, c.complete("OK"))
        checkCompleteOk(c)
        assertEquals(true, parent.isActive)
    }

    @Test
    fun testParentActiveOnChildException() {
        val parent = Job()
        val c = CompletableDeferred<String>(parent)
        checkFresh(c)
        assertEquals(true, parent.isActive)
        assertEquals(true, c.completeExceptionally(TestException()))
        checkCompleteTestException(c)
        assertEquals(true, parent.isActive)
    }

    @Test
    fun testParentActiveOnChildCancellation() {
        val parent = Job()
        val c = CompletableDeferred<String>(parent)
        checkFresh(c)
        assertEquals(true, parent.isActive)
        assertEquals(true, c.cancel())
        checkCancel(c)
        assertEquals(true, parent.isActive)
    }

    @Test
    fun testAwait() = runTest {
        expect(1)
        val c = CompletableDeferred<String>()
        launch(coroutineContext, CoroutineStart.UNDISPATCHED) {
            expect(2)
            assertEquals("OK", c.await()) // suspends
            expect(5)
            assertEquals("OK", c.await()) // does not suspend
            expect(6)
        }
        expect(3)
        c.complete("OK")
        expect(4)
        yield() // to launch
        finish(7)
    }

    @Test
    fun testCancelAndAwaitParentWaitChildren() = runTest {
        expect(1)
        val parent = CompletableDeferred<String>()
        launch(coroutineContext, start = CoroutineStart.UNDISPATCHED, parent = parent) {
            expect(2)
            try {
                yield() // will get cancelled
            } finally {
                expect(5)
            }
        }
        expect(3)
        parent.cancel()
        expect(4)
        try {
            parent.await()
        } catch (e: CancellationException) {
            finish(6)
        }
    }

    @Test
    fun testCompleteAndAwaitParentWaitChildren() = runTest {
        expect(1)
        val parent = CompletableDeferred<String>()
        launch(coroutineContext, start = CoroutineStart.UNDISPATCHED, parent = parent) {
            expect(2)
            try {
                yield() // will get cancelled
            } finally {
                expect(5)
            }
        }
        expect(3)
        parent.complete("OK")
        expect(4)
        assertEquals("OK", parent.await())
        finish(6)
    }

    private inline fun <reified T: Throwable> assertThrows(block: () -> Unit) {
        try {
            block()
            fail("Should not complete normally")
        } catch (e: Throwable) {
            assertTrue(e is T)
        }
    }

    class TestException : Throwable()
}