namespace Ocr.Cli.Monitor;

public abstract class TaskMonitor : ITaskMonitor
{
  /// <inheritdoc />
  public TimeSpan Interval { get; init; } = TimeSpan.FromSeconds(1);

  private readonly ICollection<(string? Name, Task Task)> _tasks;

  protected static IReadOnlyDictionary<TaskStatus, string> StatusMap { get; } =
    new Dictionary<TaskStatus, string>
    {
      { TaskStatus.RanToCompletion, "DONE" },
      { TaskStatus.Faulted, "FAULT" },
      { TaskStatus.Canceled, "CANCL" },
      { TaskStatus.Created, "WAIT" },
      { TaskStatus.WaitingToRun, "WAIT" },
      { TaskStatus.WaitingForActivation, "WAIT" },
      { TaskStatus.Running, "RUN" },
      { TaskStatus.WaitingForChildrenToComplete, "RUN" },
    };

  protected TaskMonitor(IEnumerable<(string? Name, Task Task)> tasks) => _tasks = tasks.ToArray();

  protected TaskMonitor(IEnumerable<Task> tasks) :
    this(tasks.Select(t => (t.Id.ToString(), t))!)
  { }

  public Task Run()
  {
    var waitTask = Task.WhenAll(_tasks.Select(i => i.Task));

    while (!waitTask.Wait(Interval))
    {
      OnUpdate(_tasks);
    }

    return waitTask;
  }

  protected abstract void OnUpdate(ICollection<(string? Name, Task Task)> tasks);
}
