<?php

declare(strict_types=1);

namespace App\Framework\Quality\PHPStan\Rules\Naming;

use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Node\InClassNode;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;

/**
 * Enforces Interface Naming Convention:
 * - NO "Interface" suffix
 * - Descriptive names (Cache, Logger, Repository, not CacheInterface)
 *
 * @implements Rule<InClassNode>
 */
final class InterfaceNamingRule implements Rule
{
    public function getNodeType(): string
    {
        return InClassNode::class;
    }

    /**
     * @param InClassNode $node
     */
    public function processNode(Node $node, Scope $scope): array
    {
        $classReflection = $node->getClassReflection();

        // Only check interfaces
        if (! $classReflection->isInterface()) {
            return [];
        }

        $shortName = $classReflection->getNativeReflection()->getShortName();
        $errors = [];

        // Rule: NO "Interface" suffix
        if (str_ends_with($shortName, 'Interface')) {
            $suggestedName = preg_replace('/Interface$/', '', $shortName);

            $errors[] = RuleErrorBuilder::message(sprintf(
                'Interface "%s" should not have "Interface" suffix. Rename to "%s".',
                $shortName,
                $suggestedName
            ))
            ->identifier('naming.interface.noSuffix')
            ->tip('Interfaces should be named by their behavior or contract: Cache, Logger, Repository')
            ->build();
        }

        return $errors;
    }
}
