using System;
using System.Collections.Generic;
using Jellyfin.Plugin.JRay.Models;
namespace Jellyfin.Plugin.JRay.Services;
///
/// Resolves the effective prioritise/ignore action for an item from the
/// configured rules. More specific scopes win: an Item rule overrides a
/// Series rule, which overrides a Genre rule. Because a given scope+value can
/// hold only one action, the only conflicts possible are across scopes, and
/// specificity resolves those.
///
public static class PolicyResolver
{
///
/// Computes the effective action for an item, or null if no rule matches.
///
/// The configured rules.
/// The item's id.
/// The item's series id, or if it is not an episode.
/// The item's genres.
/// The effective , or null when unruled.
public static PolicyAction? Resolve(
IReadOnlyList rules,
Guid itemId,
Guid seriesId,
IReadOnlyList genres)
{
ArgumentNullException.ThrowIfNull(rules);
PolicyAction? itemAction = null;
PolicyAction? seriesAction = null;
PolicyAction? genreAction = null;
var itemIdStr = itemId.ToString("D");
var seriesIdStr = seriesId == Guid.Empty ? null : seriesId.ToString("D");
foreach (var rule in rules)
{
switch (rule.Scope)
{
case PolicyScope.Item:
if (string.Equals(rule.Value, itemIdStr, StringComparison.OrdinalIgnoreCase))
{
itemAction = rule.Action;
}
break;
case PolicyScope.Series:
if (seriesIdStr is not null && string.Equals(rule.Value, seriesIdStr, StringComparison.OrdinalIgnoreCase))
{
seriesAction = rule.Action;
}
break;
case PolicyScope.Genre:
if (genres is not null && MatchesGenre(genres, rule.Value))
{
genreAction = rule.Action;
}
break;
}
}
return itemAction ?? seriesAction ?? genreAction;
}
private static bool MatchesGenre(IReadOnlyList genres, string value)
{
for (var i = 0; i < genres.Count; i++)
{
if (string.Equals(genres[i], value, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
}