using System.Threading; using System.Threading.Tasks; using Jellyfin.Plugin.SRFPlay.Api; using Jellyfin.Plugin.SRFPlay.Api.Models; using Jellyfin.Plugin.SRFPlay.Services.Interfaces; using Microsoft.Extensions.Logging; namespace Jellyfin.Plugin.SRFPlay.Services; /// /// Service for fetching media composition with caching support. /// This consolidates the cache-check → API-fetch → cache-store pattern. /// public class MediaCompositionFetcher : IMediaCompositionFetcher { private readonly ILogger _logger; private readonly IMetadataCache _metadataCache; private readonly ISRFApiClientFactory _apiClientFactory; /// /// Initializes a new instance of the class. /// /// The logger. /// The metadata cache. /// The API client factory. public MediaCompositionFetcher( ILogger logger, IMetadataCache metadataCache, ISRFApiClientFactory apiClientFactory) { _logger = logger; _metadataCache = metadataCache; _apiClientFactory = apiClientFactory; } /// public async Task GetMediaCompositionAsync( string urn, CancellationToken cancellationToken, int? cacheDurationOverride = null) { if (string.IsNullOrEmpty(urn)) { _logger.LogDebug("GetMediaCompositionAsync called with null/empty URN"); return null; } var config = Plugin.Instance?.Configuration; if (config == null) { _logger.LogWarning("Plugin configuration is null, cannot fetch media composition"); return null; } var cacheDuration = cacheDurationOverride ?? config.CacheDurationMinutes; // Try cache first var mediaComposition = _metadataCache.GetMediaComposition(urn, cacheDuration); if (mediaComposition != null) { _logger.LogDebug("Cache hit for URN: {Urn}", urn); return mediaComposition; } // Fetch from API _logger.LogDebug("Cache miss for URN: {Urn}, fetching from API", urn); using var apiClient = _apiClientFactory.CreateClient(); mediaComposition = await apiClient.GetMediaCompositionByUrnAsync(urn, cancellationToken).ConfigureAwait(false); if (mediaComposition != null) { _metadataCache.SetMediaComposition(urn, mediaComposition); _logger.LogDebug("Cached media composition for URN: {Urn}", urn); } else { _logger.LogWarning("Failed to fetch media composition for URN: {Urn}", urn); } return mediaComposition; } }