<commit_before><?php
/*
 * PSX is an open source PHP framework to develop RESTful APIs.
 * For the current version and information visit <https://phpsx.org>
 *
 * Copyright 2010-2022 <NAME> <<EMAIL>>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace PSX\Schema\Transformer;

use PSX\Schema\Exception\TransformerException;
use PSX\Schema\Parser\TypeSchema\BCLayer;
use PSX\Schema\TransformerInterface;

/**
 * Transform an existing JSON Schema to a valid TypeSchema
 *
 * @author  <NAME> <<EMAIL>>
 * @license http://www.apache.org/licenses/LICENSE-2.0
 * @link    https://phpsx.org
 */
class JsonSchema implements TransformerInterface
{
    public function transform(\stdClass $schema): \stdClass
    {
        $keywords = [];
        $definitions = new \stdClass();
        foreach ($schema as $key => $value) {
            if ($key === 'definitions' || $key === '$defs') {
                $definitions = $value;
            } else {
                $keywords[$key] = $value;
            }
        }

        $defs = [];
        if ($definitions instanceof \stdClass) {
            foreach ($definitions as $name => $type) {
                if ($type instanceof \stdClass) {
                    $defs[$name] = $this->convertSchema($type, $defs);
                }
            }
        }

        $root = null;
        if (!empty($keywords)) {
            $result = $this->convertSchema((object) $keywords, $defs);
            if (!isset($result->{'$ref'})) {
                throw new TransformerException('The root schema must be an object');
            }

            $root = $result->{'$ref'};
        }

        $result = new \stdClass();
        $result->definitions = $defs;
        if ($root !== null) {
            $result->{'$ref'} = $root;
        }

        return $result;
    }

    private function convertSchema(\stdClass $schema, array &$definitions): \stdClass
    {
        $schema = BCLayer::transform($schema);<commit_msg>add array conversion at root level<commit_after><?php
/*
 * PSX is an open source PHP framework to develop RESTful APIs.
 * For the current version and information visit <https://phpsx.org>
 *
 * Copyright 2010-2022 <NAME> <<EMAIL>>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace PSX\Schema\Transformer;

use PSX\Schema\Exception\TransformerException;
use PSX\Schema\Parser\TypeSchema\BCLayer;
use PSX\Schema\TransformerInterface;

/**
 * Transform an existing JSON Schema to a valid TypeSchema
 *
 * @author  <NAME> <<EMAIL>>
 * @license http://www.apache.org/licenses/LICENSE-2.0
 * @link    https://phpsx.org
 */
class JsonSchema implements TransformerInterface
{
    public function transform(\stdClass $schema): \stdClass
    {
        $keywords = [];
        $definitions = new \stdClass();
        foreach ($schema as $key => $value) {
            if ($key === 'definitions' || $key === '$defs') {
                $definitions = $value;
            } else {
                $keywords[$key] = $value;
            }
        }

        $defs = [];
        if ($definitions instanceof \stdClass) {
            foreach ($definitions as $name => $type) {
                if ($type instanceof \stdClass) {
                    $defs[$name] = $this->convertSchema($type, $defs);
                }
            }
        }

        $root = null;
        if (!empty($keywords)) {
            // in case we have an array at the top level we transform it to an object
            if (isset($keywords['type']) && $keywords['type'] === 'array') {
                $keywords = [
                    'type' => 'object',
                    'properties' => (object) [
                        'entries' => (object) $keywords,
                    ]
                ];
            }

            $result = $this->convertSchema((object) $keywords, $defs);
            if (!isset($result->{'$ref'})) {
                throw new TransformerException('The root schema must be an object');
            }

            $root = $result->{'$ref'};
        }

        $result = new \stdClass();
        $result->definitions = $defs;
        if ($root !== null) {
            $result->{'$ref'} = $root;
        }

        return $result;
    }

    private function convertSchema(\stdClass $schema, array &$definitions): \stdClass
    {
        $schema = BCLayer::transform($schema);
{'fraction_non_alphanumeric': 0.12841121495327104, 'fraction_numerical': 0.005233644859813084, 'mean_word_length': 2.1625295508274234, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 36, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4111006', 'n_tokens_mistral': 1489, 'n_tokens_neox': 1425, 'n_words': 458}