<?php

namespace MintyPHP\Tests\Architecture;

use FilesystemIterator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;

trait ModuleExtractionContractSupport
{
    /**
     * @param list<string> $files
     * @param list<string> $forbiddenSnippets
     */
    private function assertFilesDoNotContain(array $files, array $forbiddenSnippets): void
    {
        foreach ($files as $file) {
            $content = file_get_contents($file);
            self::assertIsString($content);

            foreach ($forbiddenSnippets as $snippet) {
                self::assertStringNotContainsString($snippet, $content, $file);
            }
        }
    }

    /**
     * @return list<string> Lines matching the pattern
     */
    private function grepDir(string $dir, string $pattern, array $extensions): array
    {
        $hits = [];
        if (!is_dir($dir)) {
            return $hits;
        }

        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS),
            RecursiveIteratorIterator::LEAVES_ONLY
        );

        foreach ($iterator as $file) {
            $ext = $file->getExtension();
            $matchesExt = false;
            foreach ($extensions as $allowedExt) {
                if ('*.' . $ext === $allowedExt) {
                    $matchesExt = true;
                    break;
                }
            }
            if (!$matchesExt) {
                continue;
            }

            $lines = file($file->getPathname(), FILE_IGNORE_NEW_LINES);
            if ($lines === false) {
                continue;
            }
            foreach ($lines as $lineNum => $line) {
                if (preg_match($pattern, $line)) {
                    $relative = str_replace(dirname(__DIR__, 2) . '/', '', $file->getPathname());
                    $hits[] = sprintf('%s:%d: %s', $relative, $lineNum + 1, trim($line));
                }
            }
        }

        return $hits;
    }
}
