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

use nulib\tests\TestCase;
use nur\sery\wip\schema\SchemaException;
use nur\sery\wip\schema\types\IType;

class ScalarSchemaTest extends TestCase {
  const NULL_SCHEMA = [
    "type" => [null],
    "default" => null,
    "title" => null,
    "required" => false,
    "nullable" => true,
    "desc" => null,
    "analyzer_func" => null,
    "extractor_func" => null,
    "parser_func" => null,
    "normalizer_func" => null,
    "messages" => null,
    "formatter_func" => null,
    "format" => null,
    "" => ["scalar"],
    "schema" => null,
    "name" => null,
    "pkey" => null,
    "header" => null,
    "composite" => null,
  ];

  static function schema(array $schema): array {
    return array_merge(self::NULL_SCHEMA, $schema);
  }

  static function sanitize(array $schema): array {
    if ($schema["type"] instanceof IType) {
      $schema["type"] = [$schema["type"]->getClass()];
    }
    return $schema;
  }

  function testNormalize() {
    self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize(null));
    self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize([]));
    self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize([null]));
    self::assertException(SchemaException::class, function () {
      ScalarSchema::normalize([[]]);
    });
    self::assertException(SchemaException::class, function () {
      ScalarSchema::normalize([[null]]);
    });

    $string = self::schema(["type" => ["string"], "nullable" => false]);
    self::assertSame($string, self::sanitize(ScalarSchema::normalize("string")));
    self::assertSame($string, self::sanitize(ScalarSchema::normalize(["string"])));

    $nstring = self::schema(["type" => ["string"]]);
    self::assertSame($nstring, self::sanitize(ScalarSchema::normalize(["?string"])));
    self::assertSame($nstring, self::sanitize(ScalarSchema::normalize(["?string|null"])));
    self::assertSame($nstring, self::sanitize(ScalarSchema::normalize(["string|null"])));
    self::assertSame($nstring, self::sanitize(ScalarSchema::normalize([["?string", "null"]])));
    self::assertSame($nstring, self::sanitize(ScalarSchema::normalize([["string", "null"]])));
    self::assertSame($nstring, self::sanitize(ScalarSchema::normalize([["string", null]])));

    $key = self::schema(["type" => ["string", "int"], "nullable" => false]);
    self::assertSame($key, self::sanitize(ScalarSchema::normalize("string|int")));

    $nkey = self::schema(["type" => ["string", "int"], "nullable" => true]);
    self::assertSame($nkey, self::sanitize(ScalarSchema::normalize("?string|int")));
    self::assertSame($nkey, self::sanitize(ScalarSchema::normalize("string|?int")));
  }
}