<?php
namespace nur\sery\schema\input;

use nur\sery\cl;

/**
 * Class Input: accès à une valeur
 *
 * cette implémentation lit depuis et écrit dans une référence
 */
class Input {
  const ALLOW_EMPTY = true;

  function __construct(&$dest=null, ?array $params=null) {
    $this->dest =& $dest;
    $allowEmpty = cl::get($params, "allow_empty");
    if ($allowEmpty === null) $allowEmpty = static::ALLOW_EMPTY;
    $this->allowEmpty = $allowEmpty;
  }

  protected $dest;

  /** tester si la valeur existe sans tenir compte de $allowEmpty */
  function isPresent($key=null): bool {
    if ($key === null) return true;
    $dest = $this->dest;
    return $dest !== null && array_key_exists($key, $dest);
  }

  /**
   * @var bool comment considérer une chaine vide: "" si allowEmpty, null sinon
   */
  protected $allowEmpty;

  /** tester si la valeur est disponible en tenant compte de $allowEmpty */
  function isAvailable($key=null): bool {
    if ($key === null) return true;
    $dest = $this->dest;
    if ($dest === null || !array_key_exists($key, $dest)) return false;
    return $this->allowEmpty || $dest[$key] !== "";
  }

  function get($key=null) {
    $dest = $this->dest;
    if ($key === null) return $dest;
    if ($dest === null || !array_key_exists($key, $dest)) return null;
    $value = $dest[$key];
    if ($value === "" && !$this->allowEmpty) return null;
    return $value;
  }

  function set($value, $key=null): void {
    if ($key === null) $this->dest = $value;
    else $this->dest[$key] = $value;
  }

  function unset($key=null): void {
    if ($key === null) $this->dest = null;
    else unset($this->dest[$key]);
  }
}
