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

package kotlinx.coroutines.experimental.internal

import org.junit.Assert.*
import org.junit.Test

class LockFreeLinkedListTest {
    data class IntNode(val i: Int) : LockFreeLinkedListNode()

    @Test
    fun testSimpleAddLast() {
        val list = LockFreeLinkedListHead()
        assertContents(list)
        val n1 = IntNode(1).apply { list.addLast(this) }
        assertContents(list, 1)
        val n2 = IntNode(2).apply { list.addLast(this) }
        assertContents(list, 1, 2)
        val n3 = IntNode(3).apply { list.addLast(this) }
        assertContents(list, 1, 2, 3)
        val n4 = IntNode(4).apply { list.addLast(this) }
        assertContents(list, 1, 2, 3, 4)
        assertTrue(n1.remove())
        assertContents(list, 2, 3, 4)
        assertTrue(n3.remove())
        assertContents(list, 2, 4)
        assertTrue(n4.remove())
        assertContents(list, 2)
        assertTrue(n2.remove())
        assertFalse(n2.remove())
        assertContents(list)
    }

    @Test
    fun testCondOps() {
        val list = LockFreeLinkedListHead()
        assertContents(list)
        assertTrue(list.addLastIf(IntNode(1)) { true })
        assertContents(list, 1)
        assertFalse(list.addLastIf(IntNode(2)) { false })
        assertContents(list, 1)
        assertTrue(list.addLastIf(IntNode(3)) { true })
        assertContents(list, 1, 3)
        assertFalse(list.addLastIf(IntNode(4)) { false })
        assertContents(list, 1, 3)
    }

    @Test
    fun testRemoveTwoAtomic() {
        val list = LockFreeLinkedListHead()
        val n1 = IntNode(1).apply { list.addLast(this) }
        val n2 = IntNode(2).apply { list.addLast(this) }
        assertContents(list, 1, 2)
        assertFalse(n1.isRemoved)
        assertFalse(n2.isRemoved)
        val remove1Desc = n1.describeRemove()!!
        val remove2Desc = n2.describeRemove()!!
        val operation = object : AtomicOp<Any?>() {
            override fun prepare(affected: Any?): Any? = remove1Desc.prepare(this) ?: remove2Desc.prepare(this)
            override fun complete(affected: Any?, failure: Any?) {
                remove1Desc.complete(this, failure)
                remove2Desc.complete(this, failure)
            }
        }
        assertTrue(operation.perform(null) == null)
        assertTrue(n1.isRemoved)
        assertTrue(n2.isRemoved)
        assertContents(list)
    }

    @Test
    fun testAtomicOpsSingle() {
        val list = LockFreeLinkedListHead()
        assertContents(list)
        val n1 = IntNode(1).also { single(list.describeAddLast(it)) }
        assertContents(list, 1)
        val n2 = IntNode(2).also { single(list.describeAddLast(it)) }
        assertContents(list, 1, 2)
        val n3 = IntNode(3).also { single(list.describeAddLast(it)) }
        assertContents(list, 1, 2, 3)
        val n4 = IntNode(4).also { single(list.describeAddLast(it)) }
        assertContents(list, 1, 2, 3, 4)
        single(n3.describeRemove()!!)
        assertContents(list, 1, 2, 4)
        assertTrue(n3.describeRemove() == null)
        single(list.describeRemoveFirst())
        assertContents(list, 2, 4)
        assertTrue(n1.describeRemove() == null)
        assertTrue(n2.remove())
        assertContents(list, 4)
        assertTrue(n4.remove())
        assertContents(list)
    }

    private fun single(part: AtomicDesc) {
        val operation = object : AtomicOp<Any?>() {
            override fun prepare(affected: Any?): Any? = part.prepare(this)
            override fun complete(affected: Any?, failure: Any?) = part.complete(this, failure)
        }
        assertTrue(operation.perform(null) == null)
    }

    private fun assertContents(list: LockFreeLinkedListHead, vararg expected: Int) {
        list.validate()
        val n = expected.size
        val actual = IntArray(n)
        var index = 0
        list.forEach<IntNode> { actual[index++] = it.i }
        assertEquals(n, index)
        for (i in 0 until n) assertEquals("item i", expected[i], actual[i])
        assertEquals(expected.isEmpty(), list.isEmpty)
    }
}