/*
 * Copyright 2019 The Android Open Source Project
 *
 * 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:OptIn(InternalComposeApi::class)
package androidx.compose.runtime

import androidx.compose.runtime.mock.EmptyApplier
import androidx.compose.runtime.mock.Text
import androidx.compose.runtime.mock.View
import androidx.compose.runtime.mock.ViewApplier
import androidx.compose.runtime.mock.compositionTest
import androidx.compose.runtime.mock.expectChanges
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotStateObserver
import java.lang.ref.WeakReference
import kotlin.concurrent.thread
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest

@Stable
@OptIn(InternalComposeApi::class)
@Suppress("unused")
class JvmCompositionTests {
    // Regression test for b/202967533
    // Test taken from the bug report; reformatted to conform to lint rules.
    @OptIn(ExperimentalCoroutinesApi::class)
    @Test
    fun avoidsDeadlockInRecomposerComposerDispose() {
        val thread = thread {
            while (!Thread.interrupted()) {
                // -> synchronized(stateLock) -> recordComposerModificationsLocked
                // -> composition.recordModificationsOf -> synchronized(lock)
                Snapshot.sendApplyNotifications()
            }
        }

        for (i in 1..1000) {
            runTest(UnconfinedTestDispatcher()) {
                localRecomposerTest {
                    @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
                    var value by mutableStateOf(0)
                    val snapshotObserver = SnapshotStateObserver {}
                    snapshotObserver.start()
                    @Suppress("UNUSED_VALUE")
                    value = 4
                    val composition = Composition(EmptyApplier(), it)
                    composition.setContent {}

                    // -> synchronized(lock) -> parent.unregisterComposition(this)
                    // -> synchronized(stateLock)
                    composition.dispose()
                    snapshotObserver.stop()
                }
            }
        }

        thread.interrupt()
    }

    @Test
    @OptIn(ExperimentalCoroutinesApi::class)
    fun avoidRaceConditionWhenInvalidating() = compositionTest {
        var scope: RecomposeScope? = null
        var count = 0
        var threadException: Exception? = null
        val thread = thread {
            try {
                while (!Thread.interrupted()) {
                    scope?.invalidate()
                    count++
                }
            } catch (e: Exception) {
                threadException = e
            }
        }

        compose {
            scope = currentRecomposeScope
            Text("Some text")
            Text("Count $count")
        }

        repeat(20) {
            advance(ignorePendingWork = true)
            delay(1)
        }

        thread.interrupt()
        @Suppress("BlockingMethodInNonBlockingContext")
        thread.join()
        delay(10)
        threadException?.let { throw it }
    }

    @Test
    @OptIn(ExperimentalCoroutinesApi::class)
    fun avoidRaceConditionWhenApplyingSnapshotsInAThread() = compositionTest {
        val count = mutableStateOf(0)
        var threadException: Exception? = null

        compose {
            Text("Some text")
            Text("Count ${count.value}")
        }

        val thread = thread {
            try {
                while (!Thread.interrupted()) {
                    Snapshot.withMutableSnapshot {
                        count.value++
                    }
                }
            } catch (e: Exception) {
                threadException = e
            }
        }

        repeat(200) {
            advance(ignorePendingWork = true)
            delay(1)
        }

        thread.interrupt()
        @Suppress("BlockingMethodInNonBlockingContext")
        thread.join()
        delay(10)
        threadException?.let { throw it }
    }

    @Test // b/197064250 and others
    fun canInvalidateDuringApplyChanges() = compositionTest {
        var value by mutableStateOf(0)
        compose {
            Wrap {
                val scope = currentRecomposeScope
                ComposeNode<View, ViewApplier>(
                    factory = { View().also { it.name = "linear" } },
                    update = {
                        set(value) {
                            scope.invalidate()
                            this.attributes["value"] = value.toString()
                        }
                    }
                )
            }
        }

        value = 2
        expectChanges()
    }

    @OptIn(ExperimentalCoroutinesApi::class)
    @Test // Regression test for https://issuetracker.google.com/262356264
    fun compositionDoesNotRetainSnapshotReference() = runTest {
        localRecomposerTest { recomposer ->
            var compositionSnapshot: WeakReference<Snapshot>? = null
            val composition = Composition(UnitApplier(), recomposer)
            composition.setContent {
                compositionSnapshot = WeakReference(Snapshot.current)
            }
            assertNotNull(compositionSnapshot, "compositionSnapshot weak reference")
            repeat(10) {
                Runtime.getRuntime().gc()
            }
            assertNull(compositionSnapshot?.get(), "weak snapshot reference after forced gc")
        }
    }

    private class TestReference(val invokeCount: Int = 0) : () -> Int {
        override fun invoke(): Int = invokeCount

        // overridden equals to test if remember compares this value correctly
        override fun equals(other: Any?): Boolean {
            return other is TestReference
        }
    }

    @Composable private fun rememberWFunctionReference(ref: () -> Int): Int {
        val remembered = remember(ref) { ref() }
        assertEquals(remembered, 0)
        return remembered
    }

    // regression test for b/319810819
    @Test
    fun remember_functionReference_key() = compositionTest {
        var state by mutableIntStateOf(0)
        compose {
            // use custom ref implementation to avoid strong skipping memoizing the instance
            rememberWFunctionReference(TestReference(state))
        }
        verifyConsistent()

        state++
        advance()
        verifyConsistent()
    }

    private var count = 0
    @BeforeTest fun saveSnapshotCount() {
        count = Snapshot.openSnapshotCount()
    }

    @AfterTest fun checkSnapshotCount() {
        val afterCount = Snapshot.openSnapshotCount()
        assertEquals(count, afterCount, "A snapshot was left open after the test")
    }
}
