/*
 * Copyright 2020 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.snapshots

import androidx.compose.runtime.ExperimentalComposeApi
import androidx.compose.runtime.InternalComposeApi
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.neverEqualPolicy
import androidx.compose.runtime.referentialEqualityPolicy
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.Snapshot.Companion.current
import androidx.compose.runtime.snapshots.Snapshot.Companion.openSnapshotCount
import androidx.compose.runtime.snapshots.Snapshot.Companion.takeMutableSnapshot
import androidx.compose.runtime.snapshots.Snapshot.Companion.takeSnapshot
import androidx.compose.runtime.structuralEqualityPolicy
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertNotSame
import kotlin.test.assertSame
import kotlin.test.assertTrue
import kotlin.test.fail

class SnapshotTests {
    @Test
    fun aSnapshotCanBeCreated() {
        val snapshot = Snapshot.takeSnapshot()
        snapshot.dispose()
    }

    @Test
    fun aMutableStateCanBeCreated() {
        mutableStateOf(0)
    }

    @Test
    fun aMutableStateCanBeReadOutsideASnapshot() {
        val state by mutableStateOf(0)
        assertEquals(0, state)
    }

    @Test
    fun aMutableStateCanBeWrittenToOutsideASnapshot() {
        var state by mutableStateOf(0)
        assertEquals(0, state)
        state = 1
        assertEquals(1, state)
    }

    @Test
    fun snapshotsAreIsolatedFromGlobalChanges() {
        var state by mutableStateOf(0)
        val snapshot = Snapshot.takeSnapshot()
        try {
            state = 1
            assertEquals(1, state)
            assertEquals(0, snapshot.enter { state })
        } finally {
            snapshot.dispose()
        }
    }

    @Test
    fun mutableSnapshotsCanBeApplied() {
        var state by mutableStateOf(0)
        val snapshot = Snapshot.takeMutableSnapshot()
        try {
            snapshot.enter {
                assertEquals(0, state)
                state = 1
                assertEquals(1, state)
            }
            assertEquals(0, state)
            snapshot.apply().check()
            assertEquals(1, state)
        } finally {
            snapshot.dispose()
        }

        // The same thing can be done with an atomic block
        atomic {
            assertEquals(1, state)
            state = 2
            assertEquals(2, state)
        }
        assertEquals(2, state)
    }

    @Test
    fun multipleSnapshotsAreIsolatedAndCanBeApplied() {
        val count = 2
        val state = MutableList(count) { mutableStateOf(0) }

        // Create count snapshots
        val snapshots = MutableList(count) { Snapshot.takeMutableSnapshot() }
        try {
            snapshots.forEachIndexed { index, snapshot ->
                snapshot.enter { state[index].value = index }
            }

            // Ensure the modifications in snapshots are not visible to global
            repeat(count) {
                assertEquals(0, state[it].value)
            }

            // Ensure snapshots can see their own value but no other changes
            repeat(count) { index ->
                snapshots[index].enter {
                    repeat(count) {
                        if (it != index) assertEquals(0, state[it].value)
                        else assertEquals(it, state[it].value)
                    }
                }
            }

            // Apply all the snapshots
            repeat(count) {
                snapshots[it].apply().check()
            }

            // Global should now be able to see all changes
            repeat(count) {
                assertEquals(it, state[it].value)
            }
        } finally {
            // Dispose the snapshots
            snapshots.forEach { it.dispose() }
        }
    }

    @Test
    fun applyingASnapshotThatCollidesWithAGlobalChangeWillFail() {
        var state by mutableStateOf(0)

        val snapshot = snapshot { state = 1 }
        try {
            state = 2
            assertTrue(snapshot.apply() is SnapshotApplyResult.Failure)
            assertEquals(2, state)
        } finally {
            snapshot.dispose()
        }
    }

    @Test
    fun applyingCollidingSnapshotsWillFail() {
        var state by mutableStateOf(0)
        val snapshot1 = snapshot { state = 1 }
        val snapshot2 = snapshot { state = 2 }
        try {
            assertEquals(0, state)
            snapshot1.apply().check()
            assertEquals(1, state)
            assertTrue(snapshot2.apply() is SnapshotApplyResult.Failure)
            assertEquals(1, state)
        } finally {
            snapshot1.dispose()
            snapshot2.dispose()
        }
    }

    @Test
    fun stateReadsCanBeObserved() {
        val state = mutableStateOf(0)

        val readStates = mutableListOf<Any>()
        val snapshot = Snapshot.takeSnapshot {
            readStates.add(it)
        }
        try {

            val result = snapshot.enter { state.value }

            assertEquals(0, result)
            assertEquals(1, readStates.size)
            assertEquals(state, readStates[0])
        } finally {
            snapshot.dispose()
        }
    }

    @Test
    fun stateWritesCanBeObserved() {
        val state = mutableStateOf(0)
        val writtenStates = mutableListOf<Any>()
        val snapshot = Snapshot.takeMutableSnapshot { write ->
            writtenStates.add(write)
        }
        try {
            snapshot.enter {
                assertEquals(0, writtenStates.size)
                state.value = 2
                assertEquals(1, writtenStates.size)
            }
        } finally {
            snapshot.dispose()
        }
        assertEquals(1, writtenStates.size)
        assertEquals(state, writtenStates[0])
    }

    @Test
    fun appliesCanBeObserved() {
        val state = mutableStateOf(0)
        var observedSnapshot: Snapshot? = null
        val unregister = Snapshot.registerApplyObserver { changed, snapshot ->
            assertTrue(state in changed)
            observedSnapshot = snapshot
        }
        val snapshot = Snapshot.takeMutableSnapshot()
        try {
            snapshot.enter {
                state.value = 2
            }
            assertEquals(null, observedSnapshot)
            snapshot.apply().check()
            assertEquals(snapshot, observedSnapshot)
        } finally {
            snapshot.dispose()
            unregister.dispose()
        }
    }

    @Test
    fun globalChangesCanBeObserved() {
        val state = mutableStateOf(0)

        Snapshot.notifyObjectsInitialized()

        var applyObserved = false
        val unregister = Snapshot.registerApplyObserver { changed, _ ->
            assertTrue(state in changed)
            applyObserved = true
        }
        try {
            state.value = 2

            // Nothing should have been observed yet.
            assertFalse(applyObserved)

            // Advance the global snapshot to send apply notifications
            Snapshot.sendApplyNotifications()

            assertTrue(applyObserved)
        } finally {
            unregister.dispose()
        }
    }

    @Test
    fun aNestedSnapshotCanBeTaken() {
        val state = mutableStateOf(0)

        val snapshot = Snapshot.takeSnapshot()
        try {
            val nested = snapshot.takeNestedSnapshot()
            try {
                state.value = 1

                assertEquals(0, nested.enter { state.value })
            } finally {
                nested.dispose()
            }
        } finally {
            snapshot.dispose()
        }
    }

    @Test
    fun aNestedMutableSnapshotCanBeTaken() {
        val state = mutableStateOf(0)
        val snapshot = Snapshot.takeMutableSnapshot()
        try {
            snapshot.enter { state.value = 1 }
            val nested = snapshot.takeNestedMutableSnapshot()
            try {
                nested.enter { state.value = 2 }

                assertEquals(0, state.value)
                assertEquals(1, snapshot.enter { state.value })
                assertEquals(2, nested.enter { state.value })
            } finally {
                nested.dispose()
            }
        } finally {
            snapshot.dispose()
        }
    }

    @Test
    fun aNestedSnapshotOfAMutableSnapshotCanBeTaken() {
        val state = mutableStateOf(0)
        val snapshot = Snapshot.takeMutableSnapshot()
        try {
            snapshot.enter { state.value = 1 }
            val nested = snapshot.takeNestedSnapshot()
            try {
                snapshot.enter { state.value = 2 }

                assertEquals(0, state.value)
                assertEquals(2, snapshot.enter { state.value })
                assertEquals(1, nested.enter { state.value })
            } finally {
                nested.dispose()
            }
        } finally {
            snapshot.dispose()
        }
    }

    @Test
    fun aNestedMutableSnapshotCanBeAppliedToItsParent() {
        val state = mutableStateOf(0)
        val snapshot = Snapshot.takeMutableSnapshot()
        try {
            snapshot.enter { state.value = 1 }
            val nested = snapshot.takeNestedMutableSnapshot()
            try {

                nested.enter { state.value = 2 }
                assertEquals(0, state.value)
                assertEquals(1, snapshot.enter { state.value })
                assertEquals(2, nested.enter { state.value })

                nested.apply().check()
            } finally {
                nested.dispose()
            }
            assertEquals(0, state.value)
            assertEquals(2, snapshot.enter { state.value })

            snapshot.apply().check()
        } finally {
            snapshot.dispose()
        }

        assertEquals(2, state.value)
    }

    @Test
    fun aParentSnapshotCanAccessAStatObjectedCreateByANestedSnapshot() {
        val snapshot = Snapshot.takeMutableSnapshot()
        val state = try {
            val nested = snapshot.takeNestedMutableSnapshot()
            val state = try {
                nested.notifyObjectsInitialized()
                val state = nested.enter { mutableStateOf(1) }
                assertEquals(1, nested.enter { state.value })
                nested.apply().check()
                state
            } finally {
                nested.dispose()
            }
            assertEquals(1, snapshot.enter { state.value })
            snapshot.apply().check()
            state
        } finally {
            snapshot.dispose()
        }
        assertEquals(1, state.value)
    }

    @Test
    fun atomicChangesNest() {
        val state = mutableStateOf(0)
        atomic {
            state.value = 1
            atomic {
                state.value = 2

                assertEquals(0, Snapshot.global { state.value })
            }
            assertEquals(2, state.value)
            assertEquals(0, Snapshot.global { state.value })
        }
        assertEquals(2, state.value)
    }

    @Test
    fun siblingNestedMutableSnapshotsAreIsolatedFromEachOther() {
        val state = mutableStateOf(0)
        val snapshot = Snapshot.takeMutableSnapshot()
        try {
            snapshot.enter { state.value = 10 }

            val nested1 = snapshot.takeNestedMutableSnapshot()
            try {
                nested1.enter { state.value = 1 }
                val nested2 = snapshot.takeNestedMutableSnapshot()
                try {
                    nested2.enter { state.value = 2 }

                    assertEquals(0, state.value)
                    assertEquals(10, snapshot.enter { state.value })
                    assertEquals(1, nested1.enter { state.value })
                    assertEquals(2, nested2.enter { state.value })
                } finally {
                    nested2.dispose()
                }
            } finally {
                nested1.dispose()
            }
        } finally {
            snapshot.dispose()
        }
        assertEquals(0, state.value)
    }

    @Test
    fun readingInANestedSnapshotNotifiesTheParent() {
        val state = mutableStateOf(0)
        val read = HashSet<Any>()
        val snapshot = Snapshot.takeSnapshot { read.add(it) }
        try {
            val nested = snapshot.takeNestedSnapshot()
            try {
                assertEquals(0, nested.enter { state.value })
            } finally {
                nested.dispose()
            }
        } finally {
            snapshot.dispose()
        }
        assertTrue(read.contains(state))
    }

    @Test
    fun readingInANestedSnapshotNotifiesNestedAndItsParent() {
        val state = mutableStateOf(0)
        val parentRead = HashSet<Any>()
        val nestedRead = HashSet<Any>()
        val snapshot = Snapshot.takeSnapshot { parentRead.add(it) }
        try {
            val nested = snapshot.takeNestedSnapshot { nestedRead.add(it) }
            try {
                assertEquals(0, nested.enter { state.value })
            } finally {
                nested.dispose()
            }
        } finally {
            snapshot.dispose()
        }
        assertTrue(parentRead.contains(state))
        assertTrue(nestedRead.contains(state))
    }

    @Test
    fun writingToANestedSnapshotNotifiesTheParent() {
        val state = mutableStateOf(0)
        val written = HashSet<Any>()
        val snapshot = Snapshot.takeMutableSnapshot { written.add(it) }
        try {
            val nested = snapshot.takeNestedMutableSnapshot()
            try {
                nested.enter { state.value = 2 }
            } finally {
                nested.dispose()
            }
        } finally {
            snapshot.dispose()
        }
        assertTrue(written.contains(state))
    }

    @Test
    fun writingToANestedSnapshotNotifiesNestedAndItsParent() {
        val state = mutableStateOf(0)
        val parentWritten = HashSet<Any>()
        val nestedWritten = HashSet<Any>()
        val snapshot = Snapshot.takeMutableSnapshot { parentWritten.add(it) }
        try {
            val nested = snapshot.takeNestedMutableSnapshot { nestedWritten.add(it) }
            try {
                nested.enter { state.value = 2 }
            } finally {
                nested.dispose()
            }
        } finally {
            snapshot.dispose()
        }
        assertTrue(parentWritten.contains(state))
        assertTrue(nestedWritten.contains(state))
    }

    @Test
    fun creatingAStateInANestedSnapshotAndMutatingInParentApplies() {
        val states = mutableListOf<MutableState<Int>>()
        val snapshot = Snapshot.takeMutableSnapshot()
        try {
            val nested = snapshot.takeNestedMutableSnapshot()
            try {
                nested.enter {
                    val state = mutableStateOf(0)
                    states.add(state)
                }
                nested.apply()
            } finally {
                nested.dispose()
            }
            snapshot.enter {
                for (state in states) {
                    state.value++
                }
            }
            snapshot.apply()
        } finally {
            snapshot.dispose()
        }
        for (state in states) {
            assertEquals(1, state.value)
        }
    }

    @Test
    fun snapshotsChangesCanMerge() {
        val state = mutableStateOf(0)
        val snapshot1 = Snapshot.takeMutableSnapshot()
        val snapshot2 = Snapshot.takeMutableSnapshot()
        try {
            // Change the state to the same value in both snapshots
            snapshot1.enter { state.value = 1 }
            snapshot2.enter { state.value = 1 }

            // Still 0 until one of the snapshots is applied
            assertEquals(0, state.value)

            // Apply snapshot 1 should change the value to 1
            snapshot1.apply().check()
            assertEquals(1, state.value)

            // Applying snapshot 2 should succeed because it changed the value to the same value.
            snapshot2.apply().check()
            assertEquals(1, state.value)
        } finally {
            snapshot1.dispose()
            snapshot2.dispose()
        }
    }

    @Test
    fun mergedSnapshotsDoNotRepeatChangeNotifications() {
        val state = mutableStateOf(0)
        val snapshot1 = Snapshot.takeMutableSnapshot()
        val snapshot2 = Snapshot.takeMutableSnapshot()
        try {
            val changes = changesOf(state) {
                snapshot1.enter { state.value = 1 }
                snapshot2.enter { state.value = 1 }
                snapshot1.apply().check()
                snapshot2.apply().check()
            }
            assertEquals(1, changes)
        } finally {
            snapshot1.dispose()
            snapshot2.dispose()
        }
    }

    @Test
    fun statesWithStructuralEqualityPolicyMerge() {
        data class Value(val v1: Int, val v2: Int)
        val state = mutableStateOf(Value(1, 2), structuralEqualityPolicy())
        val snapshot1 = Snapshot.takeMutableSnapshot()
        val snapshot2 = Snapshot.takeMutableSnapshot()
        try {
            snapshot1.enter { state.value = Value(3, 4) }
            snapshot2.enter { state.value = Value(3, 4) }
            snapshot1.apply().check()
            snapshot2.apply().check()
        } finally {
            snapshot1.dispose()
            snapshot2.dispose()
        }
    }

    @Test
    fun stateUsingNeverEqualPolicyCannotBeMerged() {
        assertFailsWith(SnapshotApplyConflictException::class) {
            val state = mutableStateOf(0, neverEqualPolicy())
            val snapshot1 = Snapshot.takeMutableSnapshot()
            val snapshot2 = Snapshot.takeMutableSnapshot()
            try {
                snapshot1.enter { state.value = 1 }
                snapshot2.enter { state.value = 1 }
                snapshot1.apply().check()
                snapshot2.apply().check()
            } finally {
                snapshot1.dispose()
                snapshot2.dispose()
            }
        }
    }

    @Test
    fun changingAnEqualityPolicyStateToItsCurrentValueIsNotConsideredAChange() {
        val state = mutableStateOf(0, referentialEqualityPolicy())
        val changes = changesOf(state) {
            state.value = 0
        }
        assertEquals(0, changes)
    }

    @Test
    fun changingANeverEqualPolicyStateToItsCurrentValueIsConsideredAChange() {
        val state = mutableStateOf(0, neverEqualPolicy())
        val changes = changesOf(state) {
            state.value = 0
        }
        assertEquals(1, changes)
    }

    @Test
    fun toStringOfMutableStateDoesNotTriggerReadObserver() {
        val state = mutableStateOf(0)
        val normalReads = readsOf {
            state.value
        }
        assertEquals(1, normalReads)
        val toStringReads = readsOf {
            state.toString()
        }
        assertEquals(0, toStringReads)
    }

    @Test
    fun toStringOfDerivedStateDoesNotTriggerReadObservers() {
        val state = mutableStateOf(0)
        val derived = derivedStateOf { state.value + 1 }
        val toStringReads = readsOf {
            derived.toString()
        }
        assertEquals(0, toStringReads)
    }

    @Test
    fun toStringValueOfMutableState() {
        val state = mutableStateOf(10)
        assertEquals("MutableState(value=10)@${state.hashCode()}", state.toString())
        state.value = 20
        assertEquals("MutableState(value=20)@${state.hashCode()}", state.toString())
    }

    @Test
    fun toStringValueOfDerivedState() {
        val state = mutableStateOf(10)
        val derivedState = derivedStateOf { state.value + 10 }
        val hash = derivedState.hashCode()
        assertEquals("DerivedState(value=<Not calculated>)@$hash", derivedState.toString())
        assertEquals(20, derivedState.value)
        assertEquals("DerivedState(value=20)@$hash", derivedState.toString())
        state.value = 20
        assertEquals("DerivedState(value=<Not calculated>)@$hash", derivedState.toString())
        assertEquals(30, derivedState.value)
        assertEquals("DerivedState(value=30)@$hash", derivedState.toString())
    }

    @Test // Regression test for b/181162478
    fun nestedSnapshotsAreIsolated() {
        var state1 by mutableStateOf(0)
        var state2 by mutableStateOf(0)
        val parent = Snapshot.takeMutableSnapshot()
        parent.enter { state1 = 1 }
        Snapshot.withMutableSnapshot { state2 = 2 }
        val snapshot = parent.takeNestedSnapshot()
        parent.apply().check()
        parent.dispose()
        snapshot.enter {
            // Should se the change of state1
            assertEquals(1, state1)

            // But not the state change of state2
            assertEquals(0, state2)
        }
        snapshot.dispose()
    }

    @Test // Regression test for b/181159260
    fun readOnlySnapshotValidAfterParentDisposed() {
        var state by mutableStateOf(0)
        val parent = Snapshot.takeMutableSnapshot()
        parent.enter { state = 1 }
        val child = parent.takeNestedSnapshot()
        parent.apply().check()
        parent.dispose()
        child.enter { assertEquals(1, state) }
        val reads = mutableListOf<Any>()
        val nestedChild = child.takeNestedSnapshot { reads.add(it) }
        nestedChild.enter { assertEquals(1, state) }
        child.dispose()
        nestedChild.dispose()
    }

    @Test // Regression test for b/193006595
    fun transparentSnapshotAdvancesCorrectly() {
        val state = Snapshot.observe({}) {
            // In a transparent snapshot, advance the global snapshot
            Snapshot.notifyObjectsInitialized()

            // Create an apply an object in a snapshot
            val state = atomic {
                mutableStateOf(0)
            }

            // Ensure that the object can be accessed in the observer
            assertEquals(0, state.value)

            state
        }

        // Ensure that the object can be accessed globally.
        assertEquals(0, state.value)
    }

    // Regression test for b/199921314
    // This test lifted directly from the bug reported by chrnie@foxmail.com, modified and formatted
    // to avoid lint warnings.
    @Test
    fun testTakeSnapshotNested() {
        assertFailsWith<IllegalStateException> {
            Snapshot.withMutableSnapshot {
                val expectReadonlySnapshot = Snapshot.takeSnapshot()
                try {
                    expectReadonlySnapshot.enter {
                        var state by mutableStateOf(0)

                        // expect throw IllegalStateException:Cannot modify a state object in a
                        // read-only snapshot
                        state = 1

                        assertEquals(1, state)
                    }
                } finally {
                    expectReadonlySnapshot.dispose()
                }
            }
        }
    }

    @Test // Regression test for b/200575924
    // Test copied from b/200575924 bu chrnie@foxmail.com
    fun nestedMutableSnapshotCanNotSeeOtherSnapshotChange() {
        var state by mutableStateOf(0)

        val snapshot1 = Snapshot.takeMutableSnapshot()
        val snapshot2 = Snapshot.takeMutableSnapshot()
        try {
            snapshot2.enter {
                state = 1
            }

            snapshot1.enter {
                Snapshot.withMutableSnapshot {
                    assertEquals(0, state)
                }
            }
        } finally {
            snapshot1.dispose()
            snapshot2.dispose()
        }
    }

    @Test // Regression test for b/200575924
    // Test copied from b/200575924 by chrnie@foxmail.com
    fun nestedSnapshotCanNotSeeOtherSnapshotChange() {
        var state by mutableStateOf(0)

        val snapshot1 = Snapshot.takeMutableSnapshot()
        val snapshot2 = Snapshot.takeMutableSnapshot()
        try {
            snapshot2.enter {
                state = 1
            }

            snapshot1.enter {
                val nestedSnapshot = Snapshot.takeSnapshot()
                try {
                    nestedSnapshot.enter {
                        assertEquals(0, state)
                    }
                } finally {
                    nestedSnapshot.dispose()
                }
            }
        } finally {
            snapshot1.dispose()
            snapshot2.dispose()
        }
    }

    @Test
    fun canTakeNestedSnapshotsFromApplyObserver() {
        var takenSnapshot: Snapshot? = null
        val observer = Snapshot.registerApplyObserver { _, snapshot ->
            if (takenSnapshot != null) error("already took a nested snapshot")
            takenSnapshot = snapshot.takeNestedSnapshot()
        }

        try {
            var state by mutableStateOf("initial")
            Snapshot.withMutableSnapshot {
                state = "before observer snapshot"
            }

            state = "after observer snapshot"

            val observerSnapshot = takenSnapshot ?: fail("snapshot was not taken by observer")

            observerSnapshot.enter {
                assertEquals("before observer snapshot", state)
            }
        } finally {
            observer.dispose()
            takenSnapshot?.dispose()
        }
    }

    @Test
    fun canTakeNestedMutableSnapshotsFromApplyObserver() {
        var takenSnapshot: MutableSnapshot? = null
        val observer = Snapshot.registerApplyObserver { _, snapshot ->
            if (takenSnapshot != null) error("already took a nested snapshot")
            takenSnapshot = (snapshot as? MutableSnapshot)
                ?.takeNestedMutableSnapshot()
                ?: error("Applied snapshot was not mutable")
        }

        try {
            var state by mutableStateOf("initial")
            Snapshot.withMutableSnapshot {
                state = "before observer snapshot"
            }

            state = "after observer snapshot"

            val observerSnapshot = takenSnapshot ?: fail("snapshot was not taken by observer")

            observerSnapshot.enter {
                assertEquals("before observer snapshot", state)
                state = "change made by observer snapshot"
            }

            assertFalse(observerSnapshot.apply().succeeded,
                "applying observer snapshot with conflicting change")
        } finally {
            observer.dispose()
            takenSnapshot?.dispose()
        }
    }

    @Test
    fun cannotTakeSnapshotOfClosedSnapshotAfterApplyReturns() {
        val snapshot = takeMutableSnapshot()
        @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
        var state by mutableStateOf("initial")

        try {
            snapshot.enter { state = "mutated" }
            snapshot.apply().check()
            snapshot.takeNestedSnapshot().dispose()
            fail("taking a nested snapshot of an applied snapshot did not throw")
        } catch (ise: IllegalStateException) {
            // expected
        } finally {
            snapshot.dispose()
        }
    }

    @Test
    fun testRecordsAreReusedCorrectly() {
        val value = mutableStateOf(0)
        Snapshot.withMutableSnapshot { value.value++ }
        val mutable1 = takeMutableSnapshot()
        val readable1 = takeSnapshot()
        mutable1.enter { value.value++ }
        mutable1.apply().check()
        Snapshot.withMutableSnapshot { value.value++ }
        val v = readable1.enter { value.value }
        assertEquals(v, 1)
        readable1.dispose()
        mutable1.dispose()
    }

    @OptIn(ExperimentalComposeApi::class)
    @Test
    fun testUnsafeSnapshotEnterAndLeave() {
        val snapshot = takeSnapshot()
        try {
            val oldSnapshot = snapshot.unsafeEnter()
            try {
                assertSame(snapshot, current, "expected taken snapshot to be current")
            } finally {
                snapshot.unsafeLeave(oldSnapshot)
            }
            assertNotSame(snapshot, current, "expected taken snapshot not to be current")
        } finally {
            snapshot.dispose()
        }
    }

    @OptIn(ExperimentalComposeApi::class)
    @Test
    fun testUnsafeSnapshotLeaveThrowsIfNotCurrent() {
        val snapshot = takeSnapshot()
        try {
            try {
                snapshot.unsafeLeave(null)
                fail("unsafeLeave should have thrown")
            } catch (ise: IllegalStateException) {
                // expected
            }
        } finally {
            snapshot.dispose()
        }
    }

    @Test
    fun testNestedWithinTransparentSnapshotDisposedCorrectly() {
        val outerSnapshot = TransparentObserverSnapshot(
            previousSnapshot = currentSnapshot(),
            specifiedReadObserver = null,
            mergeParentObservers = false,
            ownsPreviousSnapshot = false
        )

        try {
            outerSnapshot.enter {
                val innerSnapshot = outerSnapshot.takeNestedSnapshot()

                try {
                    innerSnapshot.enter { }
                } finally {
                    innerSnapshot.dispose()
                }
            }
        } finally {
            outerSnapshot.dispose()
        }
    }

    @Test
    fun testNestedWithinTransparentMutableSnapshotDisposedCorrectly() {
        val outerSnapshot = TransparentObserverMutableSnapshot(
            previousSnapshot = currentSnapshot() as? MutableSnapshot,
            specifiedReadObserver = null,
            specifiedWriteObserver = null,
            mergeParentObservers = false,
            ownsPreviousSnapshot = false
        )

        try {
            outerSnapshot.enter {
                val innerSnapshot = outerSnapshot.takeNestedSnapshot()

                try {
                    innerSnapshot.enter { }
                } finally {
                    innerSnapshot.dispose()
                }
            }
        } finally {
            outerSnapshot.dispose()
        }
    }

    @Test
    fun testTransparentSnapshotMergedWithNestedReadObserver() {
        var outerChanges = 0
        var innerChanges = 0
        val state by mutableStateOf(0)

        val outerSnapshot = TransparentObserverSnapshot(
            previousSnapshot = currentSnapshot(),
            specifiedReadObserver = { outerChanges++ },
            mergeParentObservers = false,
            ownsPreviousSnapshot = false
        )

        try {
            outerSnapshot.enter {
                val innerSnapshot = outerSnapshot.takeNestedSnapshot(
                    readObserver = { innerChanges++ }
                )

                try {
                    innerSnapshot.enter {
                        state // read
                    }
                } finally {
                    innerSnapshot.dispose()
                }
            }
        } finally {
            outerSnapshot.dispose()
        }

        assertEquals(1, outerChanges)
        assertEquals(1, innerChanges)
    }

    @Test
    fun testTransparentMutableSnapshotMergedWithNestedReadObserver() {
        var outerChanges = 0
        var innerChanges = 0
        val state by mutableStateOf(0)

        val outerSnapshot = TransparentObserverMutableSnapshot(
            previousSnapshot = currentSnapshot() as? MutableSnapshot,
            specifiedReadObserver = { outerChanges++ },
            specifiedWriteObserver = null,
            mergeParentObservers = false,
            ownsPreviousSnapshot = false
        )

        try {
            outerSnapshot.enter {
                val innerSnapshot = outerSnapshot.takeNestedSnapshot(
                    readObserver = { innerChanges++ }
                )

                try {
                    innerSnapshot.enter {
                        state // read
                    }
                } finally {
                    innerSnapshot.dispose()
                }
            }
        } finally {
            outerSnapshot.dispose()
        }

        assertEquals(1, outerChanges)
        assertEquals(1, innerChanges)
    }

    private var count = 0

    @BeforeTest
    fun recordOpenSnapshots() {
        count = openSnapshotCount()
    }

    // Validate that the tests do not change the number of open snapshots
    @AfterTest
    fun validateOpenSnapshots() {
        assertEquals(count, openSnapshotCount(), "A snapshot was not disposed correctly")
    }
}

internal fun <T> changesOf(state: State<T>, block: () -> Unit): Int {
    var changes = 0
    val removeObserver = Snapshot.registerApplyObserver { states, _ ->
        if (states.contains(state)) changes++
    }
    try {
        block()
        Snapshot.sendApplyNotifications()
    } finally {
        removeObserver.dispose()
    }
    return changes
}

internal fun readsOf(block: () -> Unit): Int {
    var reads = 0
    val snapshot = Snapshot.takeSnapshot(readObserver = { reads++ })
    try {
        snapshot.enter(block)
    } finally {
        snapshot.dispose()
    }
    return reads
}

internal inline fun <T> atomic(block: () -> T): T {
    val snapshot = Snapshot.takeMutableSnapshot()
    val result: T
    try {
        result = snapshot.enter {
            block()
        }
        snapshot.apply().check()
    } finally {
        snapshot.dispose()
    }
    return result
}

internal inline fun snapshot(block: () -> Unit): MutableSnapshot {
    val snapshot = Snapshot.takeMutableSnapshot()
    snapshot.enter(block)
    return snapshot
}
