package com.correx.apps.server.research

import com.correx.core.events.EventDispatcher
import com.correx.core.events.events.EgressHostsGrantedEvent
import com.correx.core.events.types.SessionId

/** Operator context recorded on the grant emitted by [approveSourceList]. */
internal const val BATCH_SOURCE_LIST_REASON = "batch source-list approval"

/**
 * Batch fetch-approval at the source-list level (BACKLOG §D): the operator approves a whole research
 * source list at once instead of clearing each `web_fetch` per-URL. Extracts the distinct hosts from
 * [urls] (a source list's URLs, or its source_dossier source lines) and emits a single
 * [EgressHostsGrantedEvent] for [sessionId]. That grant folds into the live per-session egress
 * allowlist (commit ab7e4be) via [com.correx.core.sessions.projections.EgressAllowlistProjection], so
 * subsequent fetches to those hosts auto-clear and no longer prompt.
 *
 * No-op when [urls] yields no parseable host: nothing to grant, so no event is emitted. Returns the
 * granted host set (empty when nothing was emitted) for the caller to report back.
 */
suspend fun approveSourceList(
    dispatcher: EventDispatcher,
    sessionId: SessionId,
    urls: List<String>,
): Set<String> {
    val hosts = SourceListHosts.extract(urls)
    if (hosts.isEmpty()) return emptySet()
    dispatcher.emit(
        payload = EgressHostsGrantedEvent(
            sessionId = sessionId,
            hosts = hosts,
            reason = BATCH_SOURCE_LIST_REASON,
        ),
        sessionId = sessionId,
    )
    return hosts
}
