<?php
namespace nur\sery\wip\schema\types;

use nulib\StateException;
use nur\prop;
use nur\sery\wip\schema\input\Input;
use nur\str;

abstract class _tsimple implements IType {
  const NAME = null;

  const ALIASES = [];

  static function get_params_from_definition(?array $definition): ?array {
    return null;
  }

  /**
   * $nullable et $params doivent toujours être les derniers arguments du
   * constructeur
   */
  function __construct(bool $nullable, ?array $params=null) {
    $this->nullable = $nullable;
    $this->params = $params;
  }

  protected bool $nullable;

  protected ?array $params;

  function getName(): string {
    return static::NAME;
  }

  function getAliases(): array {
    return static::ALIASES;
  }

  function getPhpType(bool $allowNullable=true): ?string {
    $phpType = $this->getClass();
    if ($phpType === "mixed") return null;
    if ($this->nullable && $allowNullable) $phpType = "?$phpType";
    return $phpType;
  }

  function is2States(): bool {
    return false;
  }

  function get2States(): array {
    throw StateException::not_implemented();
  }

  function is3States(): bool {
    return false;
  }

  function get3States(): array {
    throw StateException::not_implemented();
  }

  function isAvailable(Input $input, $valueKey): bool {
    return $input->isAvailable($valueKey) && $input->get($valueKey) !== false;
  }

  function isNull($value): bool {
    return $value === null || $value === "";
  }

  function extract(string $value): string {
    return $value;
  }

  #############################################################################

  function getGetterName(string $name): string {
    return prop::get_getter_name($name);
  }

  function getSetterName(string $name): string {
    return prop::get_setter_name($name);
  }

  function getDeleterName(string $name): string {
    return prop::get_deletter_name($name);
  }

  function getClassConstName(string $name): string {
    return strtoupper($name);
  }

  function getObjectPropertyName(string $name): string {
    return str::us2camel($name);
  }

  function getArrayKeyName(string $name): string {
    return $name;
  }
}
