import Dispatch
import Foundation

private final class UnsafeCounter: @unchecked Sendable {
    var value = 0
}

private final class LockedCounter: @unchecked Sendable {
    private let lock = NSLock()
    private var value = 0

    func increment() {
        lock.lock()
        value += 1
        lock.unlock()
    }

    func read() -> Int {
        lock.lock()
        defer { lock.unlock() }
        return value
    }
}

func runRaceLab() {
    labHeader(
        "CONCURRENCY · Conflicting shared access versus explicit ownership",
        mechanism: "A read-modify-write is not atomic; synchronization makes the critical section indivisible."
    )

    let iterations = 200_000
    let unsafe = UnsafeCounter()
    DispatchQueue.concurrentPerform(iterations: iterations) { _ in
        unsafe.value += 1 // Intentionally racy. Run this target with Thread Sanitizer too.
    }

    let locked = LockedCounter()
    DispatchQueue.concurrentPerform(iterations: iterations) { _ in
        locked.increment()
    }

    print("Expected:       \(iterations)")
    print("Racy result:    \(unsafe.value)")
    print("Locked result:  \(locked.read())")
    print("Observation: a coincidentally correct racy result is still incorrect; Thread Sanitizer tests the access pattern.")
    print("Interview link: choose confinement, an actor, or a narrow lock based on ownership and reentrancy needs.")
}
