using JSMR.Application.Common; using JSMR.Application.Integrations.DLSite.Models; using JSMR.Infrastructure.Integrations.DLSite.Models; namespace JSMR.Infrastructure.Integrations.DLSite.Mapping; public static class DLSiteToDomainMapper { private const string OptTrial = "TRI"; private const string OptDLPlay = "DLP"; private const string OptReviews = "REV"; private const string OptOfficialTranslation = "DOT"; private const string OptAIFull = "AIG"; private const string OptAIPartial = "AIP"; private static readonly (string Code, Language Lang)[] SupportedLanguageFlags = [ ("JPN", Language.Japanese), ("ENG", Language.English), ("CHI", Language.ChineseTraditional), ("CHI_HANT", Language.ChineseTraditional), ("CHI_HANS", Language.ChineseSimplified) ]; private static readonly Dictionary TranslationLanguageMap = SupportedLanguageFlags.ToDictionary(x => x.Code, x => x.Lang, StringComparer.OrdinalIgnoreCase); public static VoiceWorkDetailCollection Map(ProductInfoCollection? productInfoCollection) { VoiceWorkDetailCollection result = []; if (productInfoCollection is null) return result; foreach (var keyValue in productInfoCollection) { string productId = keyValue.Key; ProductInfo productInfo = keyValue.Value; VoiceWorkDetails voiceWorkDetails = Map(productInfo); result[productId] = voiceWorkDetails; } return result; } public static VoiceWorkDetails Map(ProductInfo productInfo) { ArgumentNullException.ThrowIfNull(productInfo); string[] options = [.. productInfo.Options.Where(s => !string.IsNullOrWhiteSpace(s))]; HashSet optionsSet = new(options, StringComparer.OrdinalIgnoreCase); return new VoiceWorkDetails { Series = MapSeries(productInfo), Translation = MapTranslation(productInfo, optionsSet), WishlistCount = productInfo.WishlistCount, DownloadCount = productInfo.DownloadCount, RegistrationDate = productInfo.RegistrationDate, SupportedLanguages = MapSupportedLanguages(optionsSet), AI = MapAIGeneration(optionsSet), HasTrial = optionsSet.Contains(OptTrial), HasDLPlay = optionsSet.Contains(OptDLPlay), HasReviews = optionsSet.Contains(OptReviews) }; } private static VoiceWorkSeries? MapSeries(ProductInfo productInfo) { if (string.IsNullOrWhiteSpace(productInfo.TitleId) || string.IsNullOrWhiteSpace(productInfo.TitleName)) return null; return new VoiceWorkSeries { Identifier = productInfo.TitleId, Name = productInfo.TitleName }; } private static VoiceWorkTranslation? MapTranslation(ProductInfo info, HashSet options) { ProductTranslationInfo? translationInfo = info.TranslationInfo; if (translationInfo == null || string.IsNullOrWhiteSpace(translationInfo.OriginalWorkNumber) || string.IsNullOrWhiteSpace(translationInfo.Language)) return null; string languageCode = translationInfo.Language.Trim(); if (!options.Contains(languageCode)) return null; if (!TranslationLanguageMap.TryGetValue(languageCode, out Language language)) return null; string originalId = translationInfo.OriginalWorkNumber; bool isOfficial = options.Contains(OptOfficialTranslation); return new VoiceWorkTranslation { OriginalProductId = originalId, Language = language, IsOfficialTranslation = isOfficial }; } private static Language[] MapSupportedLanguages(HashSet options) { List languages = []; foreach (var (code, language) in SupportedLanguageFlags) { if (options.Contains(code) && !languages.Contains(language)) languages.Add(language); } return [.. languages]; } private static AIGeneration MapAIGeneration(HashSet options) { if (options.Contains(OptAIFull)) return AIGeneration.Full; if (options.Contains(OptAIPartial)) return AIGeneration.Partial; return AIGeneration.None; } }