<?php

namespace MintyPHP\Tests\Architecture;

trait ProjectFileAssertionSupport
{
    private function projectRootPath(): string
    {
        $root = realpath(__DIR__ . '/../..');
        $this->assertNotFalse($root, 'Project root not found.');

        return $root;
    }

    private function readProjectFile(string $path): string
    {
        $root = $this->projectRootPath();
        $fullPath = $root . '/' . $path;
        $this->assertFileExists($fullPath, 'File not found: ' . $path);

        $content = file_get_contents($fullPath);
        $this->assertNotFalse($content, 'Could not read file: ' . $path);

        return $content;
    }

    /**
     * @return list<string>
     */
    private function findPatternMatchesInPhpFiles(string $relativeDirectory, string $pattern): array
    {
        return $this->findPatternMatchesInFiles($relativeDirectory, $pattern, ['php']);
    }

    /**
     * @param list<string> $extensions
     * @return list<string>
     */
    private function findPatternMatchesInFiles(string $relativeDirectory, string $pattern, array $extensions): array
    {
        $root = $this->projectRootPath();
        $basePath = $root . '/' . $relativeDirectory;
        $this->assertDirectoryExists($basePath, 'Directory not found: ' . $relativeDirectory);

        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($basePath));
        $violations = [];

        /** @var \SplFileInfo $file */
        foreach ($iterator as $file) {
            if (!$file->isFile() || !in_array($file->getExtension(), $extensions, true)) {
                continue;
            }

            $content = file_get_contents($file->getPathname());
            $this->assertNotFalse($content, 'Could not read file: ' . $file->getPathname());

            if (!preg_match($pattern, $content)) {
                continue;
            }

            $relativePath = str_replace($root . '/', '', $file->getPathname());
            $violations[] = $relativePath;
        }

        sort($violations);
        return $violations;
    }
}
