using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Plugin.SRFPlay.Api;
using Jellyfin.Plugin.SRFPlay.Services;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Plugin.SRFPlay.Providers;
///
/// Provides metadata for SRF Play series/shows.
///
public class SRFSeriesProvider : IRemoteMetadataProvider
{
private readonly ILogger _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly IHttpClientFactory _httpClientFactory;
private readonly MetadataCache _metadataCache;
///
/// Initializes a new instance of the class.
///
/// The logger instance.
/// The logger factory.
/// The HTTP client factory.
/// The metadata cache.
public SRFSeriesProvider(
ILogger logger,
ILoggerFactory loggerFactory,
IHttpClientFactory httpClientFactory,
MetadataCache metadataCache)
{
_logger = logger;
_loggerFactory = loggerFactory;
_httpClientFactory = httpClientFactory;
_metadataCache = metadataCache;
}
///
public string Name => "SRF Play";
///
public async Task> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken)
{
var results = new List();
try
{
// Check if we have a URN to search with
if (searchInfo.ProviderIds.TryGetValue("SRF", out var urn) && !string.IsNullOrEmpty(urn))
{
_logger.LogDebug("Searching for series with URN: {Urn}", urn);
var config = Plugin.Instance?.Configuration;
if (config == null)
{
return results;
}
// Try cache first
var mediaComposition = _metadataCache.GetMediaComposition(urn, config.CacheDurationMinutes);
// If not in cache, fetch from API
if (mediaComposition == null)
{
using var apiClient = new SRFApiClient(_loggerFactory);
mediaComposition = await apiClient.GetMediaCompositionByUrnAsync(urn, cancellationToken).ConfigureAwait(false);
if (mediaComposition != null)
{
_metadataCache.SetMediaComposition(urn, mediaComposition);
}
}
if (mediaComposition?.Show != null)
{
var show = mediaComposition.Show;
results.Add(new RemoteSearchResult
{
Name = show.Title,
Overview = show.Description ?? show.Lead,
ImageUrl = show.ImageUrl,
SearchProviderName = Name,
ProviderIds = new Dictionary
{
{ "SRF", show.Urn ?? urn }
}
});
}
}
else if (!string.IsNullOrEmpty(searchInfo.Name))
{
_logger.LogDebug("Name-based search not yet implemented for: {Name}", searchInfo.Name);
// TODO: Implement name-based search when SRF provides search API
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error searching for series: {Name}", searchInfo.Name);
}
return results;
}
///
public async Task> GetMetadata(SeriesInfo info, CancellationToken cancellationToken)
{
var result = new MetadataResult();
try
{
// Check if we have a URN
if (!info.ProviderIds.TryGetValue("SRF", out var urn) || string.IsNullOrEmpty(urn))
{
_logger.LogDebug("No SRF URN found for series: {Name}", info.Name);
return result;
}
_logger.LogDebug("Fetching metadata for series URN: {Urn}", urn);
var config = Plugin.Instance?.Configuration;
if (config == null)
{
return result;
}
// Try cache first
var mediaComposition = _metadataCache.GetMediaComposition(urn, config.CacheDurationMinutes);
// If not in cache, fetch from API
if (mediaComposition == null)
{
using var apiClient = new SRFApiClient(_loggerFactory);
mediaComposition = await apiClient.GetMediaCompositionByUrnAsync(urn, cancellationToken).ConfigureAwait(false);
if (mediaComposition != null)
{
_metadataCache.SetMediaComposition(urn, mediaComposition);
}
}
if (mediaComposition?.Show == null)
{
_logger.LogWarning("No show information found for URN: {Urn}", urn);
return result;
}
var show = mediaComposition.Show;
result.Item = new Series
{
Name = show.Title,
Overview = show.Description ?? show.Lead,
ProviderIds = new Dictionary
{
{ "SRF", show.Urn ?? urn }
}
};
// Set additional metadata if available
if (!string.IsNullOrEmpty(show.Vendor))
{
result.Item.Studios = new[] { show.Vendor };
}
result.HasMetadata = true;
_logger.LogDebug("Successfully fetched metadata for series: {Title}", show.Title);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error fetching metadata for series: {Name}", info.Name);
}
return result;
}
///
public Task GetImageResponse(string url, CancellationToken cancellationToken)
{
throw new NotImplementedException("Image handling is done by SRFImageProvider");
}
}