#!/usr/bin/php
<?php
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';

use nur\b\io\CacheFile;
use nur\cli\Application;
use nur\msg;
use nur\path;
use nur\yaml;

Application::run(new class extends Application {
  const ACTION_READ = 10, ACTION_INFOS = 20, ACTION_CLEAN = 30;
  const ACTION_UPDATE = 40, ACTION_UPDATE_ADD = 41, ACTION_UPDATE_SUB = 42, ACTION_UPDATE_SET = 43;

  const ARGS = [
    "merge" => parent::ARGS,
    "purpose" => "gestion de fichiers cache",
    ["-r", "--read", "name" => "action", "value" => self::ACTION_READ,
      "help" => "Afficher le contenu d'un fichier cache",
    ],
    ["-i", "--infos", "name" => "action", "value" => self::ACTION_INFOS,
      "help" => "Afficher des informations sur le fichier cache",
    ],
    ["-k", "--clean", "name" => "action", "value" => self::ACTION_CLEAN,
      "help" => "Supprimer le fichier cache s'il a expiré",
    ],
    ["-a", "--add-duration", "args" => 1,
      "action" => [null, "->setActionUpdate", self::ACTION_UPDATE_ADD],
      "help" => "Ajouter le nombre de secondes spécifié à la durée du cache",
    ],
    ["-b", "--sub-duration", "args" => 1,
      "action" => [null, "->setActionUpdate", self::ACTION_UPDATE_SUB],
      "help" => "Enlever le nombre de secondes spécifié à la durée du cache",
    ],
    ["-s", "--set-duration", "args" => 1,
      "action" => [null, "->setActionUpdate", self::ACTION_UPDATE_SET],
      "help" => "Mettre à jour la durée du cache à la valeur spécifiée",
    ],
  ];

  protected $action = self::ACTION_READ;

  protected $updateAction, $updateDuration;

  protected $args;

  function setActionUpdate(int $action, $updateDuration): void {
    $this->action = self::ACTION_UPDATE;
    switch ($action) {
    case self::ACTION_UPDATE_SUB: $this->updateAction = -1; break;
    case self::ACTION_UPDATE_SET: $this->updateAction = 0; break;
    case self::ACTION_UPDATE_ADD: $this->updateAction = 1; break;
    }
    $this->updateDuration = $updateDuration;
  }

  protected function findCaches(string $dir, ?array &$files): void {
    foreach (glob("$dir/*") as $file) {
      if (is_dir($file)) {
        $this->findCaches($file, $files);
      } elseif (is_file($file) && fnmatch("*.cache", $file)) {
        $files[] = $file;
      }
    }
  }

  function main() {
    $files = [];
    foreach ($this->args as $arg) {
      if (is_dir($arg)) {
        $this->findCaches($arg, $files);
      } elseif (is_file($arg)) {
        $files[] = $arg;
      } else {
        msg::warning("$arg: fichier invalide ou introuvable");
      }
    }
    $showSection = count($files) > 1;
    foreach ($files as $file) {
      switch ($this->action) {
      case self::ACTION_READ:
        if ($showSection) msg::section($file);
        $cache = new CacheFile($file, [
          "duration" => "INF",
          "override_duration" => true,
        ]);
        yaml::dump($cache->get());
        break;
      case self::ACTION_INFOS:
        if ($showSection) msg::section($file);
        $cache = new CacheFile($file);
        yaml::dump($cache->getInfos());
        break;
      case self::ACTION_CLEAN:
        msg::action(path::ppath($file));
        $cache = new CacheFile($file);
        try {
          if ($cache->deleteExpired()) msg::asuccess("fichier supprimé");
          else msg::astep("fichier non expiré");
        } catch (Exception $e) {
          msg::afailure(null, $e);
        }
        break;
      case self::ACTION_UPDATE:
        msg::action(path::ppath($file));
        $cache = new CacheFile($file);
        try {
          $cache->updateDuration($this->updateDuration, $this->updateAction);
          msg::asuccess("fichier mis à jour");
        } catch (Exception $e) {
          msg::afailure(null, $e);
        }
        break;
      default:
        self::die("$this->action: action non implémentée");
      }
    }
  }
});
