using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models;
using Kyoo.Utils;
using Microsoft.Extensions.Logging;
namespace Kyoo.Core.Controllers
{
///
/// A metadata provider composite that merge results from all available providers.
///
public class ProviderComposite : AProviderComposite
{
///
/// The list of metadata providers
///
private readonly ICollection _providers;
///
/// The logger used to print errors.
///
private readonly ILogger _logger;
///
/// The list of selected providers. If no provider has been selected, this is null.
///
private ICollection _selectedProviders;
///
/// Create a new with a list of available providers.
///
/// The list of providers to merge.
/// The logger used to print errors.
public ProviderComposite(IEnumerable providers, ILogger logger)
{
_providers = providers.ToArray();
_logger = logger;
}
///
public override void UseProviders(IEnumerable providers)
{
_selectedProviders = providers.ToArray();
}
///
/// Return the list of providers that should be used for queries.
///
/// The list of providers to use, respecting the .
private IEnumerable _GetProviders()
{
return _selectedProviders?
.Select(x => _providers.FirstOrDefault(y => y.Provider.Slug == x.Slug))
.Where(x => x != null)
?? _providers;
}
///
public override async Task Get(T item)
{
T ret = item;
foreach (IMetadataProvider provider in _GetProviders())
{
try
{
ret = Merger.Merge(ret, await provider.Get(ret));
}
catch (Exception ex)
{
_logger.LogError(ex, "The provider {Provider} could not get a {Type}",
provider.Provider.Name, typeof(T).Name);
}
}
return ret;
}
///
public override async Task> Search(string query)
{
List ret = new();
foreach (IMetadataProvider provider in _GetProviders())
{
try
{
ret.AddRange(await provider.Search(query));
}
catch (Exception ex)
{
_logger.LogError(ex, "The provider {Provider} could not search for {Type}",
provider.Provider.Name, typeof(T).Name);
}
}
return ret;
}
}
}