<commit_before><?php

/*
 * This file is part of the API Platform project.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace ApiPlatform\SchemaGenerator;

use ApiPlatform\SchemaGenerator\Model\Class_;
use Nette\InvalidArgumentException as NetteInvalidArgumentException;
use Nette\PhpGenerator\PhpFile;
use PhpCsFixer\Cache\NullCacheManager;
use PhpCsFixer\Differ\NullDiffer;
use PhpCsFixer\Error\ErrorsManager;
use PhpCsFixer\FixerFactory;
use PhpCsFixer\Linter\Linter;
use PhpCsFixer\RuleSet as LegacyRuleSet;
use PhpCsFixer\RuleSet\RuleSet;
use PhpCsFixer\Runner\Runner;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\String\Inflector\InflectorInterface;
use Twig\Environment;

final class FilesGenerator
{
    use LoggerAwareTrait;

    private InflectorInterface $inflector;
    private Printer $printer;
    private Environment $twig;
    private Filesystem $filesystem;
    private SymfonyStyle $io;

    public function __construct(InflectorInterface $inflector, Printer $printer, Environment $twig, SymfonyStyle $io)
    {
        $this->inflector = $inflector;
        $this->printer = $printer;
        $this->twig = $twig;
        $this->filesystem = new Filesystem();
        $this->io = $io;
    }

    /**
     * Generates files.
     *
     * @param Class_[]      $classes
     * @param Configuration $config
     */
    public function generate(array $classes, array $config): void
    {
        $interfaceMappings = [];
        $generatedFiles = [];

        foreach ($classes as $className => $class) {
            $classDir = $this->namespaceToDir($class->namespace, $config);
            $this->filesystem->mkdir($classDir);

            $path = sprintf('%s%s.php', $classDir, $className);

            $file = null;
            if (file_exists($path) && is_file($path) && is_readable($path) && $fileContent = file_get_contents($path)) {
                $confirmation = $this->io->askQuestion(new ConfirmationQuestion(sprintf('File "%s" already exists, use it (if no it will be overwritten)?', $path)));
                if ($confirmation) {
                    $file = PhpFile::fromCode($fileContent);
                    $this->logger ? $this->logger->info(sprintf('Using "%s" as base file.', $path)) : null;
                }
            }

            try {
                file_put_contents($path, $this->printer->printFile($class->toNetteFile($config, $this->inflector, $file)));
            } catch (NetteInvalidArgumentException $exception) {
                $this->logger ? $this->logger->warning($exception->getMessage()) : null;
            }

            $generatedFiles[] = $path;

            if (null !== $class->interfaceNamespace()) {
                $interfaceDir = $this->namespaceToDir($class->interfaceNamespace(), $config);
                $this->filesystem->mkdir($interfaceDir);

                $path = sprintf('%s%s.php', $interfaceDir, $class->interfaceName());
                $generatedFiles[] = $path;
                file_put_contents($path, $this->printer->printFile($class->interfaceToNetteFile($config['header'] ?? null)));

                if ($config['doctrine']['resolveTargetEntityConfigPath'] && !$class->isAbstract) {
                    $interfaceMappings[$class->interfaceNamespace().'\\'.$class->interfaceName()] = $class->namespace.'\\'.$className;
                }
            }<commit_msg>fix: use choice instead of confirmation question (#380)<commit_after><?php

/*
 * This file is part of the API Platform project.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace ApiPlatform\SchemaGenerator;

use ApiPlatform\SchemaGenerator\Model\Class_;
use Nette\InvalidArgumentException as NetteInvalidArgumentException;
use Nette\PhpGenerator\PhpFile;
use PhpCsFixer\Cache\NullCacheManager;
use PhpCsFixer\Differ\NullDiffer;
use PhpCsFixer\Error\ErrorsManager;
use PhpCsFixer\FixerFactory;
use PhpCsFixer\Linter\Linter;
use PhpCsFixer\RuleSet as LegacyRuleSet;
use PhpCsFixer\RuleSet\RuleSet;
use PhpCsFixer\Runner\Runner;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\String\Inflector\InflectorInterface;
use Twig\Environment;

final class FilesGenerator
{
    use LoggerAwareTrait;

    private InflectorInterface $inflector;
    private Printer $printer;
    private Environment $twig;
    private Filesystem $filesystem;
    private SymfonyStyle $io;

    public function __construct(InflectorInterface $inflector, Printer $printer, Environment $twig, SymfonyStyle $io)
    {
        $this->inflector = $inflector;
        $this->printer = $printer;
        $this->twig = $twig;
        $this->filesystem = new Filesystem();
        $this->io = $io;
    }

    /**
     * Generates files.
     *
     * @param Class_[]      $classes
     * @param Configuration $config
     */
    public function generate(array $classes, array $config): void
    {
        $interfaceMappings = [];
        $generatedFiles = [];

        foreach ($classes as $className => $class) {
            $classDir = $this->namespaceToDir($class->namespace, $config);
            $this->filesystem->mkdir($classDir);

            $path = sprintf('%s%s.php', $classDir, $className);

            $file = null;
            if (file_exists($path) && is_file($path) && is_readable($path) && $fileContent = file_get_contents($path)) {
                $choice = $this->io->askQuestion(new ChoiceQuestion(sprintf('File "%s" already exists, keep your changes and update it (use) or overwrite it (overwrite)?', $path), ['use', 'overwrite'], 0));
                if ('use' === $choice) {
                    $file = PhpFile::fromCode($fileContent);
                    $this->logger ? $this->logger->info(sprintf('Using "%s" as base file.', $path)) : null;
                }
            }

            try {
                file_put_contents($path, $this->printer->printFile($class->toNetteFile($config, $this->inflector, $file)));
            } catch (NetteInvalidArgumentException $exception) {
                $this->logger ? $this->logger->warning($exception->getMessage()) : null;
            }

            $generatedFiles[] = $path;

            if (null !== $class->interfaceNamespace()) {
                $interfaceDir = $this->namespaceToDir($class->interfaceNamespace(), $config);
                $this->filesystem->mkdir($interfaceDir);

                $path = sprintf('%s%s.php', $interfaceDir, $class->interfaceName());
                $generatedFiles[] = $path;
                file_put_contents($path, $this->printer->printFile($class->interfaceToNetteFile($config['header'] ?? null)));

                if ($config['doctrine']['resolveTargetEntityConfigPath'] && !$class->isAbstract) {
                    $interfaceMappings[$class->interfaceNamespace().'\\'.$class->interfaceName()] = $class->namespace.'\\'.$className;
                }
            }
{'fraction_non_alphanumeric': 0.13632069105142394, 'fraction_numerical': 0.0008098258874342017, 'mean_word_length': 2.962566844919786, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2061846', 'n_tokens_mistral': 2145, 'n_tokens_neox': 2093, 'n_words': 440}