using Process.Interface;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Process.Abstract;

/// <summary>
/// Basic implementation for <see cref="IProcessorChain{TInput, TOutput}"/>s
/// </summary>
/// <typeparam name="TInput"><see cref="IProcessor{TInput,TOutput}"/> input type</typeparam>
/// <typeparam name="TOutput"><see cref="IProcessor{TInput,TOutput}"/> output type</typeparam>
public class ProcessorChain<TInput, TOutput>
  : Processor<TInput, TOutput>, IProcessorChain<TInput, TOutput>
{
  /// <inheritdoc />
  public ICollection<IProcessor> Processors { get; } = new List<IProcessor>();

  /// <inheritdoc />
  public override IEnumerable<TOutput> Process(IEnumerable<TInput> inputs)
  {
    return Processors
      .Aggregate(
        (IEnumerable)inputs,
        (current, processor) => processor.Process(current)
      )
      .Cast<TOutput>()
      .Where(k => k is not null)
      .ToArray();
  }
}
