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

use nulib\cl;
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 tarray extends _tstring {
  const NAME = "array";

  const SPLIT_PATTERN = '/\s+/';
  const FORMAT = " ";

  public static function get_params_from_definition(?array $definition): ?array {
    $params = parent::get_params_from_definition($definition);
    $splitPattern = $definition["split_pattern"] ?? null;
    if ($splitPattern !== null) $params["split_pattern"] = $splitPattern;
    $format = $definition["format"] ?? null;
    if ($format !== null) $params["format"] = $format;
    return $params;
  }

  static function ensure_array(&$array): void {
    if (!is_array($array)) $array = cl::with($array);
  }

  static function ensure_narray(&$array): void {
    if ($array !== null) self::ensure_array($array);
  }

  function getClass(): string {
    return "array";
  }

  function isValid($value, ?bool &$normalized=null): bool {
    $normalized = is_array($value);
    return is_scalar($value) || is_array($value);
  }

  function parse(string $value) {
    $pattern = $this->params["split_pattern"] ?? static::SPLIT_PATTERN;
    return preg_split($pattern, $value);
  }

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

  function format($value, $format=null): string {
    if ($value === null) return "";
    $format ??= $this->params["format"] ?? static::FORMAT;
    return implode($format, $value);
  }
}
