package com.correx.testing.fixtures

import com.correx.core.events.events.EventMetadata
import com.correx.core.events.events.EventPayload
import com.correx.core.events.events.NewEvent
import com.correx.core.events.types.EventId
import com.correx.core.events.types.SessionId
import com.correx.infrastructure.persistence.InMemoryEventStore
import com.correx.core.sessions.projections.Projection
import com.correx.core.sessions.projections.replay.DefaultEventReplayer
import kotlinx.datetime.Instant

class DeterministicHarness {
    val eventStore: InMemoryEventStore = InMemoryEventStore()
    val clock: Instant = Instant.parse("2026-01-01T00:00:00Z")

    private var eventCounter = 0

    suspend fun givenEvents(sessionId: SessionId, vararg payloads: EventPayload) {
        val events = payloads.map { payload ->
            val eventId = EventId("event-${eventCounter++}")
            NewEvent(
                metadata = EventMetadata(
                    eventId = eventId,
                    sessionId = sessionId,
                    timestamp = clock,
                    schemaVersion = 1,
                    causationId = null,
                    correlationId = null
                ),
                payload = payload
            )
        }
        eventStore.appendAll(events)
    }

    fun <S> rebuild(sessionId: SessionId, projection: Projection<S>): S {
        val replayer = DefaultEventReplayer(eventStore, projection)
        return replayer.rebuild(sessionId)
    }
}
