JuliaStrelkova/project-lvl2-s427

View on GitHub
src/ASTBuilder.php

Summary

Maintainability
A
35 mins
Test Coverage
<?php
declare(strict_types=1);

namespace Gendiff;

class ASTBuilder
{
    public const DELETED = 'deleted';
    public const ADDED = 'added';
    public const CHANGED = 'changed';
    public const UNCHANGED = 'unchanged';
    public const NESTED = 'nested';

    public function buildAst(array $firstDataSet, array $secondDataSet): array
    {
        $keysFirstAndSecondDataSet = $this->getUniqueKeys($firstDataSet, $secondDataSet);

        return array_map(
            function (string $key) use ($firstDataSet, $secondDataSet) {

                if (array_key_exists($key, $firstDataSet) && array_key_exists($key, $secondDataSet)) {
                    if (is_array($firstDataSet[$key]) && is_array($secondDataSet[$key])) {
                        return $this->buildNode(
                            self::NESTED,
                            $key,
                            null,
                            null,
                            $this->buildAst($firstDataSet[$key], $secondDataSet[$key])
                        );
                    }

                    if ($firstDataSet[$key] === $secondDataSet[$key]) {
                        return $this->buildNode(self::UNCHANGED, $key, $firstDataSet[$key]);
                    }

                    return $this->buildNode(self::CHANGED, $key, $firstDataSet[$key], $secondDataSet[$key]);
                }

                if (!array_key_exists($key, $secondDataSet)) {
                    return $this->buildNode(self::DELETED, $key, $firstDataSet[$key]);
                }

                return $this->buildNode(self::ADDED, $key, null, $secondDataSet[$key]);
            },
            $keysFirstAndSecondDataSet
        );
    }

    private function buildNode(string $type, string $key, $oldValue = null, $newValue = null, $children = null): array
    {
        return [
            'type' => $type,
            'key' => $key,
            'newValue' => $newValue,
            'oldValue' => $oldValue,
            'children' => $children,
        ];
    }

    private function getUniqueKeys(array $firstDataSet, array $secondDataSet): array
    {
        return array_values(
            array_unique(
                array_merge(array_keys($firstDataSet), array_keys($secondDataSet))
            )
        );
    }
}