<?php
namespace nur\b\io;

use Exception;
use Generator;

/**
 * Class CacheFile: un fichier que l'on construit si besoin
 */
class CacheFile extends FileCachedValue {
  function __construct(?string $file=null, ?array $params=null) {
    if ($file !== null) $params["file"] = $file;
    parent::__construct($params);
  }

  /** @var callable */
  protected $compute;

  protected function compute() {
    $compute = $this->compute;
    return $compute !== null? $compute(): null;
  }

  /**
   * écrire le résultat de la fonction $compute dans le fichier si le cache a
   * expiré ou si le fichier n'existe pas. sinon, la fonction n'est pas appelée
   */
  function put(callable $compute, bool $noCache=false) {
    $this->compute = $compute;
    try {
      if ($this->shouldUpdate($noCache)) {
        try {
          $data = $compute();
          if ($data instanceof Generator) {
            #XXX ne pas utiliser iterator_to_array() qui semble avoir un souci
            # avec les générateurs imbriqués
            $items = [];
            foreach ($data as $item) {
              $items[] = $item;
            }
            $data = $items;
          }
          if ($this->shouldCache($data)) {
            $this->save($data, $this->ppFile);
          } else {
            # ne pas garder le fichier s'il ne faut pas mettre en cache
            unlink($this->ppFile);
          }
        } catch (Exception $e) {
          // si une erreur se produit, ne pas garder le fichier
          unlink($this->ppFile);
          throw $e;
        }
      } else {
        $data = $this->load($this->ppFile);
      }
      return $data;
    } finally {
      $this->cleanup();
    }
  }
}