using JSMR.Application.Common; using JSMR.Application.Integrations.DLSite.Models; using JSMR.Infrastructure.Common.SupportedLanguages; 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 (string Code, ISupportedLanguage Lang)[] SupportedLanguageFlags2 = [ ("JPN", new JapaneseLanguage()), ("ENG", new EnglishLanguage()), ("CHI", new ChineseLanguage()), ("CHI_HANT", new TraditionalChineseLanguage()), ("CHI_HANS", new SimplifiedChineseLanguage()) ]; private static readonly Dictionary TranslationLanguageMap = SupportedLanguageFlags.ToDictionary(x => x.Code, x => x.Lang, StringComparer.OrdinalIgnoreCase); private static readonly Dictionary AgeRatingMap = new() { { 1, AgeRating.AllAges }, { 2, AgeRating.R15 }, { 3, AgeRating.R18 } }; 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), AgeRating = MapAgeRating(productInfo) }; } 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 ISupportedLanguage[] MapSupportedLanguages(HashSet options) { List languages = []; foreach (var (code, language) in SupportedLanguageFlags2) { 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; } private static AgeRating MapAgeRating(ProductInfo productInfo) { if (AgeRatingMap.TryGetValue(productInfo.AgeCategory, out AgeRating ageRating)) return ageRating; return AgeRating.R18; } }