using JSMR.Application.Common; using JSMR.Application.Scanning.Contracts; using JSMR.Application.Scanning.Ports; using JSMR.Domain.Entities; using JSMR.Infrastructure.Common.Languages; using JSMR.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace JSMR.Infrastructure.Ingestion; public class EnglishVoiceWorkUpdater(AppDbContext dbContext, ILanguageIdentifier languageIdentifier) : IVoiceWorkUpdater { public async Task UpsertAsync(IReadOnlyCollection ingests, CancellationToken cancellationToken) { EnglishVoiceWorkUpsertContext upsertContext = await CreateUpsertContextAsync(ingests, cancellationToken); foreach (VoiceWorkIngest ingest in ingests) { Validate(ingest, upsertContext); VoiceWorkUpsertResult result = upsertContext.Results[ingest.ProductId]; if (result.Issues.Count > 0) { result.Status = VoiceWorkUpsertStatus.Skipped; continue; } UpsertEnglishVoiceWork(ingest, upsertContext); result.Status = VoiceWorkUpsertStatus.Updated; } await dbContext.SaveChangesAsync(cancellationToken); return [.. upsertContext.VoiceWorks.Select(x => x.Value.VoiceWorkId)]; } private async Task CreateUpsertContextAsync(IReadOnlyCollection ingests, CancellationToken cancellationToken) { string[] makerIds = [.. ingests.Select(i => i.MakerId).Where(s => !string.IsNullOrWhiteSpace(s)).Distinct()]; string[] productIds = [.. ingests.Select(i => i.ProductId).Distinct()]; EnglishVoiceWorkUpsertContext upsertContext = new( Circles: await dbContext.Circles .Where(c => makerIds.Contains(c.MakerId)) .ToDictionaryAsync(c => c.MakerId, cancellationToken), VoiceWorks: await dbContext.VoiceWorks .Where(v => productIds.Contains(v.ProductId)) .Include(v => v.EnglishVoiceWorks) .Include(v => v.Localizations) .ToDictionaryAsync(v => v.ProductId, cancellationToken), Results: productIds.ToDictionary( productId => productId, productId => new VoiceWorkUpsertResult() ) ); return upsertContext; } private void Validate(VoiceWorkIngest ingest, EnglishVoiceWorkUpsertContext upsertContext) { VoiceWorkUpsertResult result = upsertContext.Results[ingest.ProductId]; bool isTitleEnglish = languageIdentifier.GetLanguage(ingest.Title) == Language.English; bool isDescriptionEnglish = !string.IsNullOrWhiteSpace(ingest.Description) && languageIdentifier.GetLanguage(ingest.Description) == Language.English; if (!isTitleEnglish && !isDescriptionEnglish) { string message = $"Prouct title and/or description is not in English"; result.Issues.Add(new(message, VoiceWorkUpsertIssueSeverity.Information)); return; } if (upsertContext.Circles.TryGetValue(ingest.MakerId, out Circle? circle) == false) { string message = $"Unable to find circle for maker id: {ingest.MakerId}"; result.Issues.Add(new(message, VoiceWorkUpsertIssueSeverity.Error)); return; } if (upsertContext.VoiceWorks.TryGetValue(ingest.ProductId, out VoiceWork? voiceWork) == false) { string message = $"Unable to find voice work for product id: {ingest.ProductId}"; result.Issues.Add(new(message, VoiceWorkUpsertIssueSeverity.Error)); } } private void UpsertEnglishVoiceWork(VoiceWorkIngest ingest, EnglishVoiceWorkUpsertContext upsertContext) { EnglishVoiceWork englishVoiceWork = GetOrAddEnglishVoiceWork(ingest, upsertContext); englishVoiceWork.ProductName = ingest.Title; englishVoiceWork.Description = ingest.Description; englishVoiceWork.IsValid = true; } private EnglishVoiceWork GetOrAddEnglishVoiceWork(VoiceWorkIngest ingest, EnglishVoiceWorkUpsertContext upsertContext) { VoiceWork voiceWork = upsertContext.VoiceWorks[ingest.ProductId]; EnglishVoiceWork? englishVoiceWork = voiceWork.EnglishVoiceWorks.FirstOrDefault(); if (englishVoiceWork is null) { englishVoiceWork = new EnglishVoiceWork { VoiceWork = voiceWork, ProductName = string.Empty, Description = string.Empty }; dbContext.EnglishVoiceWorks.Add(englishVoiceWork); //upsertContext.VoiceWorks[ingest.ProductId] = voiceWork; } return englishVoiceWork; } }