using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Scheduling; using ErsatzTV.Core.Scheduling; namespace ErsatzTV.Infrastructure.Scheduling; public class RerunMediaCollectionEnumerator : IMediaCollectionEnumerator { private readonly CollectionKey _collectionKey; private readonly IRerunHelper _rerunHelper; private IMediaCollectionEnumerator _enumerator; private RerunMediaCollectionEnumerator(IRerunHelper rerunHelper, CollectionKey collectionKey) { _collectionKey = collectionKey; _rerunHelper = rerunHelper; } public CollectionEnumeratorState State => _enumerator.State; public Option Current { get { MoveToNextValid(); return _enumerator.Current; } } public Option CurrentIncludeInProgramGuide => _enumerator.CurrentIncludeInProgramGuide; public int Count => _enumerator.Count; public Option MinimumDuration => _enumerator.MinimumDuration; public void ResetState(CollectionEnumeratorState state) { _enumerator.ResetState(state); MoveToNextValid(); } public void MoveNext(Option scheduledAt) { if (_collectionKey.CollectionType is CollectionType.RerunFirstRun) { foreach (var current in Current) { foreach (var when in scheduledAt) { _rerunHelper.AddToHistory(_collectionKey, current.Id, when); } } } _enumerator.MoveNext(scheduledAt); MoveToNextValid(); } private void MoveToNextValid() { switch (_collectionKey.CollectionType) { // skip to the next first run case CollectionType.RerunFirstRun when _rerunHelper.FirstRunCount(_collectionKey) > 0: { while (_enumerator.Current.Match(current => _rerunHelper.IsRerun(_collectionKey, current.Id), false)) { _enumerator.MoveNext(Option.None); } break; } // skip to the next rerun case CollectionType.RerunRerun when _rerunHelper.RerunCount(_collectionKey) > 0: { while (_enumerator.Current.Match(current => _rerunHelper.IsFirstRun(_collectionKey, current.Id), false)) { _enumerator.MoveNext(Option.None); } break; } } } public static RerunMediaCollectionEnumerator Create( IRerunHelper rerunHelper, CollectionKey collectionKey, List mediaItems, PlaybackOrder playbackOrder, CollectionEnumeratorState state, CancellationToken cancellationToken) { IMediaCollectionEnumerator enumerator = playbackOrder switch { PlaybackOrder.Chronological => new ChronologicalMediaCollectionEnumerator(mediaItems, state), PlaybackOrder.SeasonEpisode => new SeasonEpisodeMediaCollectionEnumerator(mediaItems, state), PlaybackOrder.Shuffle => new ShuffledMediaCollectionEnumerator( mediaItems.Map(i => new GroupedMediaItem(i, null)).ToList(), state, cancellationToken), _ => new RandomizedMediaCollectionEnumerator(mediaItems, state) }; return new RerunMediaCollectionEnumerator(rerunHelper, collectionKey) { _enumerator = enumerator }; } }