<?php
namespace nur;

use nur\b\io\IOException;

/**
 * Class os: outils pour interagir avec le système d'exploitation
 */
class os {
  /**
   * créer un répertoire avec un nom unique. ce répertoire doit être supprimé
   * manuellement quand il n'est plus utilisé.
   *
   * @return string le chemin du répertoire
   * @throws IOException si une erreur se produit (impossible de créer un
   * répertoire unique après 2560 essais)
   */
  static final function mktempdir(?string $prefix=null, ?string $basedir=null): string {
    if ($basedir === null) $basedir = sys_get_temp_dir();
    if ($prefix !== null) $prefix .= "-";
    $max = 2560;
    do {
      $dir = "$basedir/$prefix".uniqid();
      $r = @mkdir($dir);
      $max--;
    } while ($r === false && $max > 0);
    if ($r === false) {
      throw IOException::last_error("$dir: unable to create directory");
    }
    return $dir;
  }

  /**
   * Supprimer un répertoire créé avec mktempdir
   *
   * un minimum de vérification est effectué qu'il s'agit bien d'un répertoire
   * généré par mktempdir
   */
  static final function rmtempdir(string $tmpdir, ?string $prefix=null, ?string $basedir=null): void {
    if ($basedir === null) $basedir = sys_get_temp_dir();
    if ($prefix !== null) $prefix .= "-";
    // 13 '?' parce que c'est la taille d'une chaine générée par uniqid()
    if (fnmatch("$basedir/$prefix?????????????", $tmpdir)) {
      shell::exec(["rm", "-rf", $tmpdir]);
    } else {
      throw new IOException("$tmpdir: n'est pas un répertoire temporaire");
    }
  }

  /**
   * supprimer tous les répertoires temporaires qui ont été créés avec le
   * suffixe spécifié dans le répertoire $basedir
   */
  static final function cleantempdirs(string $prefix, ?string $basedir=null): void {
    if ($basedir === null) $basedir = sys_get_temp_dir();
    $prefix .= "-";
    // 13 '?' parce que c'est la taille d'une chaine générée par uniqid()
    $tmpdirs = glob("$basedir/$prefix?????????????", GLOB_ONLYDIR);
    if ($tmpdirs) {
      shell::exec(array_merge(["rm", "-rf"], $tmpdirs));
    }
  }

  /** s'assurer que le répertoire $dir existe */
  static final function mkdirs(string $dir): bool {
    if (is_dir($dir)) return true;
    return mkdir($dir, 0777, true);
  }

  /** créer le répertoire qui va contenir le fichier $file */
  static final function mkdirof(string $file): bool {
    if (file_exists($file)) return true;
    $dir = path::dirname($file);
    if (file_exists($dir)) return true;
    return mkdir($dir, 0777, true);
  }

  /** retourner le répertoire $HOME */
  static final function homedir(): string {
    $homedir = getenv("HOME");
    if ($homedir === false) {
      $homedir = posix_getpwuid(posix_getuid())["dir"];
    }
    return path::abspath($homedir);
  }
}
