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

use Exception;
use nulib\php\func;
use nulib\ValueException;
use nur\sery\wip\schema\_scalar\ScalarResult;
use nur\sery\wip\schema\_scalar\ScalarSchema;
use nur\sery\wip\schema\Result;
use nur\sery\wip\schema\Schema;

class tcallable extends _tsimple {
  const NAME = "callable";

  const ALIASES = ["func", "function"];

  static function ensure_callable(&$callable): void {
    $callable = func::ensure($callable);
  }

  static function ensure_ncallable(&$callable): void {
    if ($callable !== null) self::ensure_callable($callable);
  }

  function getClass(): string {
    return func::class;
  }

  function isValid($value, ?bool &$normalized=null): bool {
    $normalized = is_callable($value);
    return func::check($value);
  }

  function parse(string $value) {
    try {
      return func::ensure($value);
    } catch (Exception $e) {
      throw new ValueException(null, null, 0, $e);
    }
  }

  /**
   * @var ScalarResult $result
   * @var ScalarSchema $schema
   */
  function verifix(&$value, Result $result, Schema $schema): bool {
    if ($value instanceof func) {
      $result->setNormalized();
      return false;
    } elseif (is_callable($value)) {
      $value = func::with($value);
      $result->setNormalized();
      return true;
    } elseif (is_string($value)) {
      try {
        $value = $this->parse($value);
        $result->setValid();
        return true;
      } catch (ValueException $e) {
      }
    }
    $result->setInvalid($value, $schema);
    return false;
  }

  function format($value, $format=null): string {
  }
}
