<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\Utils\Rector\Rector;

use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Chill\Utils\Rector\Tests\ChillBundleMakeDataProviderStaticForAbstractFilterTest\ChillBundleMakeDataProviderStaticForAbstractFilterTestRectorTest;
use PhpParser\Node;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
 * @see ChillBundleMakeDataProviderStaticForAbstractFilterTestRectorTest
 */
final class ChillBundleMakeDataProviderStaticForAbstractFilterTestRector extends AbstractRector
{
    public function getRuleDefinition(): RuleDefinition
    {
        return new RuleDefinition(
            'Make static each method which provide data',
            [
                new CodeSample('', ''),
            ]
        );
    }

    public function getNodeTypes(): array
    {
        return [Node\Stmt\Class_::class];
    }

    public function refactor(Node $node)
    {
        if (!$node instanceof Node\Stmt\Class_) {
            return null;
        }

        if (null === $node->extends) {
            return null;
        }

        if (AbstractFilterTest::class !== $node->extends->toString()) {
            return null;
        }

        $new = [];
        $matched = false;

        foreach ($node->stmts as $k => $stmt) {
            if (!$stmt instanceof Node\Stmt\ClassMethod) {
                $new[] = $stmt;
                continue;
            }

            if ('getFormData' === $stmt->name->name || 'getQueryBuilders' === $stmt->name->name) {
                if ($stmt->isStatic()) {
                    $new[] = $stmt;
                    continue;
                }

                $matched = true;
                $method = new Node\Stmt\ClassMethod($stmt->name->name);
                $method->flags = Node\Stmt\Class_::MODIFIER_PUBLIC | Node\Stmt\Class_::MODIFIER_STATIC;
                $method->returnType = match ($stmt->name->name) {
                    'getFormData' => new Node\Identifier('array'),
                    'getQueryBuilders' => new Node\Identifier('iterable'),
                };

                foreach ($stmt->getStmts() as $s) {
                    $method->stmts[] = $s;
                }

                $new[] = $method;
            } else {
                $new[] = $stmt;
            }
        }

        if (!$matched) {
            return null;
        }

        $node->stmts = $new;

        return $node;
    }
}
