import Foundation

/// A service that preinstalls the speech model assets a transcription needs, for the Recording feature.
///
/// The service resolves the locales the transcriber supports and downloads the speech model assets of a given locale ahead of its
/// first transcription. The outcomes of a preinstallation are emitted through ``events`` rather than thrown: a host can surface the
/// started, cancelled, and failed downloads however it sees fit, while a download that finishes — or assets that are already
/// installed — emit nothing.
public protocol Preinstalling: Sendable {

    // MARK: Properties

    /// The stream of events the service emits while preinstalling.
    var events: AsyncStream<PreinstallingEvent> { get }

    // MARK: Methods

    /// Preinstalls the speech model assets for the supported equivalent of the given locale.
    ///
    /// - Parameter locale: The locale to preinstall the speech model assets for.
    func preinstall(for locale: Locale) async

    /// Returns the supported locale equivalent to the given locale.
    ///
    /// - Parameter locale: The locale to find a supported equivalent for.
    /// - Returns: The supported equivalent, or `nil` when the transcriber supports none.
    func supportedLocale(equivalentTo locale: Locale) async -> Locale?

    /// Returns the locales the transcriber supports.
    ///
    /// - Returns: The supported locales, including ones whose assets are not installed yet.
    func supportedLocales() async -> [Locale]

}

// MARK: - Events

/// An event emitted by a ``Preinstalling`` service while preinstalling speech model assets.
///
/// Every case carries the locale the preinstallation was requested for — not its supported equivalent — so a host can match the
/// event against the locale it passed to ``Preinstalling/preinstall(for:)``.
public enum PreinstallingEvent: Sendable {
    /// The download of the locale's speech model assets was cancelled before it finished.
    case cancelled(Locale)
    /// The download of the locale's speech model assets failed.
    case failed(Locale)
    /// The download of the locale's speech model assets started.
    case started(Locale)
}
