package com.correx.core.events.stores

import com.correx.core.events.events.NewEvent
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.types.SessionId
import kotlinx.coroutines.flow.Flow


interface EventStore {
    /**
     * Append a single event to the store.
     * Must enforce:
     * - monotonic per-session sequence
     * - idempotency by eventId
     * - causal consistency rules (if enforced here, otherwise in kernel)
     */
    suspend fun append(event: NewEvent): StoredEvent

    /**
     * Append multiple events atomically (same session preferred).
     */
    suspend fun appendAll(events: List<NewEvent>): List<StoredEvent>

    /**
     * Read events for a session in strict sequence order.
     */
    fun read(sessionId: SessionId): List<StoredEvent>

    /**
     * Read events from a specific sequence offset (for replay/resume).
     */
    fun readFrom(sessionId: SessionId, fromSequence: Long): List<StoredEvent>

    /**
     * Get last sequence number for session.
     */
    fun lastSequence(sessionId: SessionId): Long?

    /**
     * Subscribe to live events for a session. Emits each event as it is appended.
     * Does not replay historical events — use [readFrom] for catch-up before subscribing.
     */
    fun subscribe(sessionId: SessionId): Flow<StoredEvent>

    fun subscribeAll(): Flow<StoredEvent>

    suspend fun lastGlobalSequence(): Long

    /**
     * Iterate every event in the store across all sessions, in monotonic insertion order.
     * Intended for batch jobs (e.g. CAS liveness scans). Implementations should stream lazily.
     */
    fun allEvents(): Sequence<StoredEvent>

    /**
     * Return all known session ids in the store.
     * Implementations should derive this from the session index, not by scanning allEvents().
     */
    fun allSessionIds(): Set<SessionId>
}
