<?php
namespace nur;

use nur\b\io\FileReader;
use nur\b\io\IOException;
use nur\b\io\IReader;
use nur\b\ValueException;

/**
 * Class reader: des outils pour lire des valeurs depuis une destination
 */
class reader {
  const INPUT_MAP = [
    "-" => "php://stdin",
    "/dev/stdin" => "php://stdin",
  ];
  const INPUT_MODES = [
    "php://stdin" => "r",
  ];

  /**
   * ouvrir le cas échéant le fichier spécifié pour écriture
   *
   * @throws IOException
   */
  static final function with($input, ?string $mode=null): IReader {
    if ($input instanceof IReader) return $input;
    if ($mode === null) $mode = FileReader::DEFAULT_MODE;
    if (!is_resource($input)) {
      if (array_key_exists($input, self::INPUT_MAP)) {
        $input = self::INPUT_MAP[$input];
      }
      if (array_key_exists($input, self::INPUT_MODES)) {
        $mode = self::INPUT_MODES[$input];
      }
    }
    return new FileReader($input, $mode);
  }

  /**
   * lire toutes les lignes de $input
   *
   * @throws IOException
   */
  static final function read_lines($input): array {
    $close = !($input instanceof IReader);
    $reader = self::with($input);
    try {
      return $reader->readLines();
    } finally {
      $reader->close($close);
    }
  }

  /**
   * lire le contenu du fichier $input
   *
   * @throws ValueException si $input n'est pas un string ni une instance de
   * {@link IReader}
   * @throws IOException si une erreur de lecture s'est produite
   */
  public static final function get_contents($input): string {
    if ($input === null) {
      $contents = stream_get_contents(STDIN);
      if ($contents === false) throw IOException::last_error();
    } elseif (is_string($input)) {
      $contents = file_get_contents($input);
      if ($contents === false) throw IOException::last_error();
    } elseif ($input instanceof IReader) {
      $contents = $input->getContents();
    } else {
      throw ValueException::unexpected_type(["string", IReader::class], $input);
    }
    return $contents;
  }
}
