<?php
namespace nur\sery\schema;

use ArrayAccess;
use IteratorAggregate;
use nur\sery\schema\_assoc\AssocValue;
use nur\sery\schema\_list\ListValue;
use nur\sery\schema\_scalar\ScalarValue;
use nur\sery\schema\types\IType;

abstract class Value implements ArrayAccess, IteratorAggregate {
  function isAssoc(?AssocValue &$assoc=null): bool { return false; }
  function isList(?ListValue &$list=null): bool { return false; }
  function isScalar(?ScalarValue &$scalar=null): bool { return false; }

  /** spécifier la valeur destination gérée par cet objet */
  abstract function reset(&$dest, $destKey=null, bool $verifix=true): self;

  /**
   * Obtenir la liste des clés valides pour les valeurs accessibles via cet
   * objet
   */
  abstract function getKeys(): array;

  /** obtenir un objet pour gérer la valeur spécifiée */
  abstract function getValue($key=null): Value;

  function getIterator() {
    foreach ($this->getKeys() as $key) {
      yield $key => $this->getValue($key);
    }
  }

  /** retourner le type associé à la valeur */
  abstract function getType(): IType;

  /** retourner true si la valeur existe */
  abstract function isPresent(): bool;

  /** retourner true si la valeur est disponible */
  abstract function isAvailable(): bool;

  /** supprimer la valeur */
  abstract function unset(): void;

  /** remplacer la valeur */
  abstract function set($value): self;

  /** obtenir le résultat de l'appel de la fonction {@link set()} */
  abstract function getResult(): Result;

  /** retourner true si la valeur est valide */
  abstract function isValid(): bool;

  /** obtenir la valeur */
  abstract function get($default=null);

  /** retourner true si la valeur est dans sa forme normalisée */
  abstract function isNormalized(): bool;

  /** formatter la valeur pour affichage */
  abstract function format($format=null): string;
}
