package port

import "time"

// StreamEvent represents an event to be published on a stream.
// Events are delivered to SSE clients and can be replayed using Last-Event-ID.
type StreamEvent struct {
	// ID uniquely identifies this event for Last-Event-ID reconnection support.
	// Format: "{streamID}:{sequence}". Populated by the publisher on Publish().
	ID string

	// Type identifies the event category (e.g., "build.output", "build.completed").
	// Use the BuildEvent* constants from the worker package for build events.
	Type string

	// TaskID associates the event with a specific task for filtering and replay.
	// Defaults to the stream ID if not explicitly set.
	TaskID string

	// Timestamp records when the event was created or published.
	// Populated by the publisher if zero when Publish() is called.
	Timestamp time.Time

	// Sequence is a monotonically increasing number within a stream.
	// Used for ordering and detecting missed events.
	Sequence int64

	// Data contains the event-specific payload as key-value pairs.
	// Contents vary by event type.
	Data map[string]any
}

// StreamPublisher defines operations for managing SSE event streams.
type StreamPublisher interface {
	// Subscribe creates a subscription to events for the given stream ID.
	// Returns a channel that will receive events and a cleanup function.
	Subscribe(streamID string) (<-chan StreamEvent, func())

	// SubscribeFromID creates a subscription starting from a specific event ID.
	// This is used for reconnection with Last-Event-ID support.
	// Events since lastEventID will be replayed before new events are delivered.
	SubscribeFromID(streamID string, lastEventID string) (<-chan StreamEvent, func())

	// Publish sends an event to all subscribers of a stream.
	// Returns the generated event ID.
	Publish(streamID string, event StreamEvent) string

	// Close closes a stream and all its subscriptions.
	Close(streamID string)
}
