<?php
namespace nur\sery\wip\os\proc;

class tasks {
  static function pf(string $name): string {
    $envname = envs::get();
    return "/tasks/$envname/$name";
  }

  /** le verrou doit être posé avant l'appel de cette méthode */
  private static function _list(bool $include_invalids, bool $sort): array {
    $tmpfiles = glob(self::pf("*.task"));
    if ($tmpfiles === false) return [];
    $tasks = [];
    foreach ($tmpfiles as $taskfile) {
      $task = new ManagedTask($taskfile);
      if (!$include_invalids && !$task->isValid()) {
        continue;
      }
      $tasks[] = [$taskfile, $task];
    }
    if ($sort) {
      clearstatcache();
      usort($tasks, function ($fta, $ftb) {
        /**
         * @var ManagedTask $ta
         * @var ManagedTask $tb
         */
        [$fa, $ta] = $fta;
        [$fb, $tb] = $ftb;
        # comparer l'état "running"
        $wa = $ta->isStarted() && !$ta->isDone();
        $wb = $tb->isStarted() && !$tb->isDone();
        $c = -base::compare($wa, $wb);
        if ($c != 0) return $c;
        # comparer la date de dernière modification du fichier
        $mta = filemtime($fa);
        $mtb = filemtime($fb);
        return -base::compare($mta, $mtb);
      });
    }
    return $tasks;
  }

  /** supprimer toutes les tâches */
  static function delete_all(): void {
    lock::exlusive(ManagedTask::LOCK);
    try {
      foreach (self::_list(true, false) as [$taskfile, $task]) {
        unlink($taskfile);
      }
    } finally {
      lock::release(ManagedTask::LOCK);
    }
  }

  /**
   * retourner la liste des tâches valides
   * @return ManagedTask[]
   */
  static function list(?string $selectId=null): array {
    $tasks = [];
    lock::exlusive(ManagedTask::LOCK);
    try {
      foreach (self::_list(false, true) as [$taskfile, $task]) {
        $id = $task->getId();
        if ($selectId !== null && $id !== $selectId) continue;
        $tasks[$id] = $task;
      }
    } finally {
      lock::release(ManagedTask::LOCK);
    }
    return $tasks;
  }
}
