using MeetingAssistant.LaunchProfiles; using Microsoft.Extensions.Options; namespace MeetingAssistant.Transcription; public sealed class ConfiguredSpeechRecognitionPipelineFactory : ISpeechRecognitionPipelineFactory { private readonly IReadOnlyDictionary builders; private readonly MeetingAssistantOptions options; private readonly ILaunchProfileOptionsProvider? launchProfiles; public ConfiguredSpeechRecognitionPipelineFactory( IEnumerable builders, IOptions options) : this(builders, options, launchProfiles: null) { } public ConfiguredSpeechRecognitionPipelineFactory( IEnumerable builders, IOptions options, ILaunchProfileOptionsProvider? launchProfiles) { this.options = options.Value; this.launchProfiles = launchProfiles; this.builders = builders .GroupBy(builder => builder.ProviderName, StringComparer.OrdinalIgnoreCase) .ToDictionary( group => group.Key, group => group.Count() == 1 ? group.Single() : throw new InvalidOperationException( $"Speech recognition pipeline provider '{group.Key}' is registered more than once."), StringComparer.OrdinalIgnoreCase); if (this.builders.Count == 0) { throw new InvalidOperationException("No speech recognition pipeline builders are registered."); } } public ISpeechRecognitionPipeline Create() { return Create(null); } public ISpeechRecognitionPipeline Create(string? launchProfileName) { var profileOptions = ResolveOptions(launchProfileName); if (!builders.TryGetValue(profileOptions.Recording.TranscriptionProvider, out var builder)) { throw new InvalidOperationException( $"Unsupported speech recognition pipeline '{profileOptions.Recording.TranscriptionProvider}'."); } return builder.Create(profileOptions); } private MeetingAssistantOptions ResolveOptions(string? launchProfileName) { if (launchProfiles is not null) { return launchProfiles.GetRequiredProfile(launchProfileName).Options; } if (string.IsNullOrWhiteSpace(launchProfileName) || launchProfileName.Equals(ConfigurationLaunchProfileOptionsProvider.DefaultProfileName, StringComparison.OrdinalIgnoreCase)) { return options; } throw new InvalidOperationException( $"Launch profile '{launchProfileName}' was requested, but no launch profile provider is registered."); } }