<commit_before><?php

/**
 * Author: <NAME> <<EMAIL>>
 * Date: 7/25/15
 * Time: 5:15 PM.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace NilPortugues\Api\JsonApi\Helpers;

use NilPortugues\Api\JsonApi\JsonApiTransformer;
use NilPortugues\Serializer\Serializer;

final class DataIncludedHelper
{
    /**
     * @param \NilPortugues\Api\Mapping\Mapping[] $mappings
     * @param array                               $array
     * @param array                               $data
     */
    public static function setResponseDataIncluded(array &$mappings, array $array, array &$data)
    {
        foreach ($array as $value) {
            if (is_array($value)) {
                if (array_key_exists(Serializer::CLASS_IDENTIFIER_KEY, $value)) {
                    $attributes = [];
                    $relationships = [];
                    $type = $value[Serializer::CLASS_IDENTIFIER_KEY];

                    self::addToRelationshipsArray($mappings, $data, $value, $type, $relationships, $attributes);
                    self::addToIncludedArray($mappings, $data, $attributes, $value);
                    continue;
                }

                if (is_array($value)) {
                    foreach ($value as $inArrayValue) {
                        if (is_array($inArrayValue)) {
                            self::setResponseDataIncluded($mappings, $inArrayValue, $data);
                        }
                    }
                }
            }
        }
    }

    /**
     * @param \NilPortugues\Api\Mapping\Mapping[] $mappings
     * @param array                               $data
     * @param array                               $value
     * @param string                              $type
     * @param array                               $relationships
     * @param array                               $attributes
     */
    private static function addToRelationshipsArray(
        array &$mappings,
        array &$data,
        array &$value,
        $type,
        array &$relationships,
        array &$attributes
    ) {
        foreach ($value as $propertyName => $attribute) {
            if (PropertyHelper::isAttributeProperty($mappings, $propertyName, $type)) {
                $propertyName = DataAttributesHelper::transformToValidMemberName($propertyName);

                if (array_key_exists(Serializer::CLASS_IDENTIFIER_KEY, $attribute)) {
                    self::setResponseDataIncluded($mappings, $value, $data);

                    $relationships[$propertyName] = array_merge(
                        DataLinksHelper::setResponseDataLinks($mappings, $attribute),
                        [
                            JsonApiTransformer::DATA_KEY => [
                                $propertyName => PropertyHelper::setResponseDataTypeAndId(
                                        $mappings,
                                        $attribute
                                    ),
                            ],
                        ],
                        $mappings[$type]->getRelationships()
                    );

                    continue;
                }
                $attributes[$propertyName] = $attribute;
            }
        }


        if(!empty($data[JsonApiTransformer::INCLUDED_KEY])) {
            $data[JsonApiTransformer::INCLUDED_KEY] = array_values(array_unique($data[JsonApiTransformer::INCLUDED_KEY], SORT_REGULAR));
        }
    }

    /**
     * @param \NilPortugues\Api\Mapping\Mapping[] $mappings
     * @param array                               $data
     * @param array                               $attributes
     * @param array                               $value
     */
    private static function addToIncludedArray(array &$mappings, array &$data, array &$attributes, array &$value)
    {
        if (count($attributes) > 0) {
            $includedData = PropertyHelper::setResponseDataTypeAndId($mappings, $value);

            if (self::hasIdKey($includedData)) {
                $arrayData = array_merge(
                    [
                        JsonApiTransformer::TYPE_KEY => $includedData[JsonApiTransformer::TYPE_KEY],
                        JsonApiTransformer::ID_KEY => $includedData[JsonApiTransformer::ID_KEY],
                        JsonApiTransformer::ATTRIBUTES_KEY => $attributes,
                        JsonApiTransformer::RELATIONSHIPS_KEY => [],
                    ],
                    DataLinksHelper::setResponseDataLinks($mappings, $value)
                );

                $relationshipData = [];
                self::addRelationshipsToIncludedResources(
                    $mappings,
                    $relationshipData,
                    $value,
                    $value[Serializer::CLASS_IDENTIFIER_KEY],
                    $attributes
                );

                if ($relationshipData) {
                    $arrayData[JsonApiTransformer::RELATIONSHIPS_KEY] = array_merge(
                        $arrayData[JsonApiTransformer::RELATIONSHIPS_KEY],
                        $relationshipData
                    );
                }

                $data[JsonApiTransformer::INCLUDED_KEY][] = array_filter($arrayData);
            }
        }
    }

    /**
     * @param array  $mappings
     * @param array  $data
     * @param array  $value
     * @param string $type
     */
    private static function addRelationshipsToIncludedResources(
        array &$mappings,
        array &$data,
        array &$value,
        $type
    ) {
        foreach ($value as $propertyName => $attribute) {
            if (PropertyHelper::isAttributeProperty($mappings, $propertyName, $type)) {
                $propertyName = DataAttributesHelper::transformToValidMemberName($propertyName);

                if (is_array($attribute) && array_key_exists(Serializer::CLASS_IDENTIFIER_KEY, $attribute)) {
                    $data[$propertyName][JsonApiTransformer::DATA_KEY] = PropertyHelper::setResponseDataTypeAndId($mappings, $attribute);

                    continue;
                }
            }
        }
    }

    /**<commit_msg>Solving include duplicated resources<commit_after><?php

/**
 * Author: <NAME> <<EMAIL>>
 * Date: 7/25/15
 * Time: 5:15 PM.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace NilPortugues\Api\JsonApi\Helpers;

use NilPortugues\Api\JsonApi\JsonApiTransformer;
use NilPortugues\Serializer\Serializer;

final class DataIncludedHelper
{
    /**
     * @param \NilPortugues\Api\Mapping\Mapping[] $mappings
     * @param array                               $array
     * @param array                               $data
     */
    public static function setResponseDataIncluded(array &$mappings, array $array, array &$data)
    {
        foreach ($array as $value) {
            if (is_array($value)) {
                if (array_key_exists(Serializer::CLASS_IDENTIFIER_KEY, $value)) {
                    $attributes = [];
                    $relationships = [];
                    $type = $value[Serializer::CLASS_IDENTIFIER_KEY];

                    self::addToRelationshipsArray($mappings, $data, $value, $type, $relationships, $attributes);
                    self::addToIncludedArray($mappings, $data, $attributes, $value);
                    continue;
                }

                if (is_array($value)) {
                    foreach ($value as $inArrayValue) {
                        if (is_array($inArrayValue)) {
                            self::setResponseDataIncluded($mappings, $inArrayValue, $data);
                        }
                    }
                }
            }
        }
    }

    /**
     * @param \NilPortugues\Api\Mapping\Mapping[] $mappings
     * @param array                               $data
     * @param array                               $value
     * @param string                              $type
     * @param array                               $relationships
     * @param array                               $attributes
     */
    private static function addToRelationshipsArray(
        array &$mappings,
        array &$data,
        array &$value,
        $type,
        array &$relationships,
        array &$attributes
    ) {
        foreach ($value as $propertyName => $attribute) {
            if (PropertyHelper::isAttributeProperty($mappings, $propertyName, $type)) {
                $propertyName = DataAttributesHelper::transformToValidMemberName($propertyName);

                if (array_key_exists(Serializer::CLASS_IDENTIFIER_KEY, $attribute)) {
                    self::setResponseDataIncluded($mappings, $value, $data);

                    $relationships[$propertyName] = array_merge(
                        DataLinksHelper::setResponseDataLinks($mappings, $attribute),
                        [
                            JsonApiTransformer::DATA_KEY => [
                                $propertyName => PropertyHelper::setResponseDataTypeAndId(
                                        $mappings,
                                        $attribute
                                    ),
                            ],
                        ],
                        $mappings[$type]->getRelationships()
                    );

                    continue;
                }
                $attributes[$propertyName] = $attribute;
            }
        }
    }

    /**
     * @param \NilPortugues\Api\Mapping\Mapping[] $mappings
     * @param array                               $data
     * @param array                               $attributes
     * @param array                               $value
     */
    private static function addToIncludedArray(array &$mappings, array &$data, array &$attributes, array &$value)
    {
        if (count($attributes) > 0) {
            $includedData = PropertyHelper::setResponseDataTypeAndId($mappings, $value);

            if (self::hasIdKey($includedData)) {
                $arrayData = array_merge(
                    [
                        JsonApiTransformer::TYPE_KEY => $includedData[JsonApiTransformer::TYPE_KEY],
                        JsonApiTransformer::ID_KEY => $includedData[JsonApiTransformer::ID_KEY],
                        JsonApiTransformer::ATTRIBUTES_KEY => $attributes,
                        JsonApiTransformer::RELATIONSHIPS_KEY => [],
                    ],
                    DataLinksHelper::setResponseDataLinks($mappings, $value)
                );

                $relationshipData = [];
                self::addRelationshipsToIncludedResources(
                    $mappings,
                    $relationshipData,
                    $value,
                    $value[Serializer::CLASS_IDENTIFIER_KEY],
                    $attributes
                );

                if ($relationshipData) {
                    $arrayData[JsonApiTransformer::RELATIONSHIPS_KEY] = array_merge(
                        $arrayData[JsonApiTransformer::RELATIONSHIPS_KEY],
                        $relationshipData
                    );
                }

                $data[JsonApiTransformer::INCLUDED_KEY][] = array_filter($arrayData);
            }
        }


        if (!empty($data[JsonApiTransformer::INCLUDED_KEY])) {
            $data[JsonApiTransformer::INCLUDED_KEY] = array_values(
                array_unique($data[JsonApiTransformer::INCLUDED_KEY], SORT_REGULAR)
            );
        }
    }

    /**
     * @param array  $mappings
     * @param array  $data
     * @param array  $value
     * @param string $type
     */
    private static function addRelationshipsToIncludedResources(
        array &$mappings,
        array &$data,
        array &$value,
        $type
    ) {
        foreach ($value as $propertyName => $attribute) {
            if (PropertyHelper::isAttributeProperty($mappings, $propertyName, $type)) {
                $propertyName = DataAttributesHelper::transformToValidMemberName($propertyName);

                if (is_array($attribute) && array_key_exists(Serializer::CLASS_IDENTIFIER_KEY, $attribute)) {
                    $data[$propertyName][JsonApiTransformer::DATA_KEY] = PropertyHelper::setResponseDataTypeAndId($mappings, $attribute);

                    continue;
                }
            }
        }
    }

    /**
{'fraction_non_alphanumeric': 0.09995171414775471, 'fraction_numerical': 0.0014485755673587638, 'mean_word_length': 1.475004979087831, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4650127', 'n_tokens_mistral': 3130, 'n_tokens_neox': 2897, 'n_words': 517}