using Microsoft.Extensions.Caching.Memory; using CodePlay.Core.Interfaces; using CodePlay.Core.Models; using CodePlay.Core.Common; using System.Security.Cryptography; using System.Text; namespace CodePlay.Core.Services; public class CachedConversionService { private readonly IConverter _innerConverter; private readonly IMemoryCache _cache; private readonly CacheOptions _cacheOptions; public CachedConversionService(IConverter innerConverter, IMemoryCache cache) { _innerConverter = innerConverter; _cache = cache; _cacheOptions = new CacheOptions { ExpirationMinutes = 60, UseCache = true }; } public async Task ConvertAsync(SyntaxTree syntaxTree, LanguageType targetLanguage, ConversionOptions? options = null, CancellationToken cancellationToken = default) { if (!_cacheOptions.UseCache) return await _innerConverter.ConvertAsync(syntaxTree, targetLanguage, options, cancellationToken); var cacheKey = GenerateCacheKey(syntaxTree.SourceCode ?? "", syntaxTree.Language.ToString(), targetLanguage.ToString(), options); if (_cache.TryGetValue(cacheKey, out var cachedResult) && cachedResult != null) return cachedResult; var result = await _innerConverter.ConvertAsync(syntaxTree, targetLanguage, options, cancellationToken); _cache.Set(cacheKey, result, TimeSpan.FromMinutes(_cacheOptions.ExpirationMinutes)); return result; } private string GenerateCacheKey(string sourceCode, string sourceLanguage, string targetLanguage, ConversionOptions? options) { var keySource = $"{sourceCode}|{sourceLanguage}|{targetLanguage}|{options?.KeepComments}|{options?.KeepDocStrings}"; using var sha256 = SHA256.Create(); return Convert.ToHexString(sha256.ComputeHash(Encoding.UTF8.GetBytes(keySource))); } public void InvalidateCache() { } } public class CacheOptions { public bool UseCache { get; set; } = true; public int ExpirationMinutes { get; set; } = 60; }