import { EVENT_SOURCE_CLOSED, type EventSourceLike } from "./useLiveQueries";

const CONNECTING = 0;
const OPEN = 1;

/** Test double for the injected EventSource constructor. */
export class FakeEventSource implements EventSourceLike {
	readonly url: string;
	closed = false;
	readyState: number = CONNECTING;
	private listeners = new Map<string, Array<(event: { data?: unknown }) => void>>();

	constructor(url: string) {
		this.url = url;
	}

	addEventListener(type: string, listener: (event: { data?: unknown }) => void): void {
		const existing = this.listeners.get(type) ?? [];
		existing.push(listener);
		this.listeners.set(type, existing);
	}

	close(): void {
		this.closed = true;
		this.readyState = EVENT_SOURCE_CLOSED;
	}

	emit(type: string, event: { data?: unknown } = {}): void {
		if (type === "open") this.readyState = OPEN;
		for (const listener of this.listeners.get(type) ?? []) listener(event);
	}

	/**
	 * A non-200 response: the browser closes the source, then dispatches one
	 * error event and never retries.
	 */
	failFatal(): void {
		this.readyState = EVENT_SOURCE_CLOSED;
		this.emit("error");
	}
}
