using System.Text.Json;
using System.Text.Json.Serialization;
namespace TeleWave.Application.Programming.Templates;
/// Как слот выбирает элемент группы.
public enum SlotStrategyType
{
/// Элементы группы по порядку позиций.
Sequential = 0,
/// Случайный элемент, не показанный последние N дней.
RandomWithCooldown = 1,
/// Всегда один и тот же элемент.
Fixed = 2,
}
/// Что делать, когда остывание отсекло всех кандидатов.
public enum CooldownFallback
{
/// Взять элемент, не игравший дольше всех.
OldestFirst = 0,
/// Проигнорировать остывание на этот выход.
IgnoreCooldown = 1,
}
///
/// Стратегия выбора элемента внутри слота. Отвечает только за выбор элемента: единицы внутри элемента
/// всегда идут по порядку от курсора — сериал не должен прыгать по сериям.
///
/// Размер блока живёт на слоте отдельно и ортогонален стратегии: любую можно скомбинировать
/// с «одна единица», «четыре подряд» или «пока не наберётся два часа».
///
public sealed record SlotStrategy(
SlotStrategyType Type = SlotStrategyType.Sequential,
/// Начинать группу заново, дойдя до конца (иначе слот останавливается).
bool RestartOnEnd = true,
/// Дней остывания для .
int CooldownDays = 0,
CooldownFallback Fallback = CooldownFallback.OldestFirst,
/// Закреплённый элемент для .
Guid? FixedElementId = null
)
{
private static readonly JsonSerializerOptions Options = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters = { new JsonStringEnumConverter() },
};
public string ToJson() => JsonSerializer.Serialize(this, Options);
/// Разбирает сохранённую стратегию. Повреждённый JSON — как отсутствие стратегии:
/// слот получит поведение по умолчанию, а не уронит генерацию всего канала.
public static SlotStrategy? FromJson(string? json)
{
if (string.IsNullOrWhiteSpace(json))
return null;
try
{
return JsonSerializer.Deserialize(json, Options);
}
catch (JsonException)
{
return null;
}
}
}