<commit_before><?php

namespace Karma;

use Gaufrette\Filesystem;
use Psr\Log\NullLogger;
use Karma\FormatterProviders\NullProvider;

class Hydrator implements ConfigurableProcessor
{
    use \Karma\Logging\LoggerAware;

    const
        TODO_VALUE = '__TODO__',
        FIXME_VALUE = '__FIXME__',
        VARIABLE_REGEX = '~<%(?P<variableName>[A-Za-z0-9_\.\-]+)%>~';

    private
        $sources,
        $suffix,
        $reader,
        $dryRun,
        $enableBackup,
        $finder,
        $formatterProvider,
        $currentFormatterName,
        $currentTargetFile,
        $systemEnvironment,
        $unusedVariables,
        $unvaluedVariables,
        $target,
        $nonDistFilesOverwriteAllowed;

    public function __construct(Filesystem $sources, Filesystem $target, Configuration $reader, Finder $finder, FormatterProvider $formatterProvider = null)
    {
        $this->logger = new NullLogger();

        $this->sources = $sources;
        $this->target = $target;
        $this->reader = $reader;
        $this->finder = $finder;

        $this->suffix = Application::DEFAULT_DISTFILE_SUFFIX;
        $this->dryRun = false;
        $this->enableBackup = false;

        $this->formatterProvider = $formatterProvider;
        if($this->formatterProvider === null)
        {
            $this->formatterProvider = new NullProvider();
        }

        $this->currentFormatterName = null;
        $this->currentTargetFile = null;
        $this->systemEnvironment = null;
        $this->unusedVariables = array_flip($reader->getAllVariables());
        $this->unvaluedVariables = array();
        $this->nonDistFilesOverwriteAllowed = false;
    }

    public function setSuffix($suffix)
    {
        $this->suffix = $suffix;

        return $this;
    }

    public function setDryRun($value = true)
    {
        $this->dryRun = (bool) $value;

        return $this;
    }

    public function enableBackup($value = true)
    {
        $this->enableBackup = (bool) $value;

        return $this;
    }
    
    public function allowNonDistFilesOverwrite($nonDistFilesOverwriteAllowed = true)
    {
        $this->nonDistFilesOverwriteAllowed = $nonDistFilesOverwriteAllowed;

        return $this;
    }

    public function setFormatterProvider(FormatterProvider $formatterProvider)
    {
        $this->formatterProvider = $formatterProvider;

        return $this;
    }

    public function setSystemEnvironment($environment)
    {
        $this->systemEnvironment = $environment;

        return $this;
    }

    public function hydrate($environment)
    {
        $files = $this->collectFiles();

        foreach($files as $file)
        {
            $this->hydrateFile($file, $environment);
        }

        $this->info(sprintf(
           '%d files generated',
            count($files)
        ));
    }

    private function collectFiles()
    {
        $pattern = sprintf('.*\%s$', $this->suffix);
        if($this->nonDistFilesOverwriteAllowed === true)
        {
            $pattern = '.*';
        }
        
        return $this->finder->findFiles(sprintf('~%s~', $pattern));
    }

    private function hydrateFile($file, $environment)
    {
        $this->currentTargetFile = preg_replace(sprintf('~(.*)(\%s)$~', $this->suffix), '$1', $file);

        if($this->nonDistFilesOverwriteAllowed)
        {
            $this->currentTargetFile = (new \SplFileInfo($this->currentTargetFile))->getFilename();
        }

        $content = $this->sources->read($file);
        $replacementCounter = $this->parseFileDirectives($file, $content, $environment);

        $targetContent = $this->injectValues($file, $content, $environment, $replacementCounter);

        $this->debug("Write $this->currentTargetFile");<commit_msg>fix: dist pattern protection for preg use<commit_after><?php

namespace Karma;

use Gaufrette\Filesystem;
use Psr\Log\NullLogger;
use Karma\FormatterProviders\NullProvider;

class Hydrator implements ConfigurableProcessor
{
    use \Karma\Logging\LoggerAware;

    const
        TODO_VALUE = '__TODO__',
        FIXME_VALUE = '__FIXME__',
        VARIABLE_REGEX = '~<%(?P<variableName>[A-Za-z0-9_\.\-]+)%>~';

    private
        $sources,
        $suffix,
        $reader,
        $dryRun,
        $enableBackup,
        $finder,
        $formatterProvider,
        $currentFormatterName,
        $currentTargetFile,
        $systemEnvironment,
        $unusedVariables,
        $unvaluedVariables,
        $target,
        $nonDistFilesOverwriteAllowed;

    public function __construct(Filesystem $sources, Filesystem $target, Configuration $reader, Finder $finder, FormatterProvider $formatterProvider = null)
    {
        $this->logger = new NullLogger();

        $this->sources = $sources;
        $this->target = $target;
        $this->reader = $reader;
        $this->finder = $finder;

        $this->suffix = Application::DEFAULT_DISTFILE_SUFFIX;
        $this->dryRun = false;
        $this->enableBackup = false;

        $this->formatterProvider = $formatterProvider;
        if($this->formatterProvider === null)
        {
            $this->formatterProvider = new NullProvider();
        }

        $this->currentFormatterName = null;
        $this->currentTargetFile = null;
        $this->systemEnvironment = null;
        $this->unusedVariables = array_flip($reader->getAllVariables());
        $this->unvaluedVariables = array();
        $this->nonDistFilesOverwriteAllowed = false;
    }

    public function setSuffix($suffix)
    {
        $this->suffix = $suffix;

        return $this;
    }

    public function setDryRun($value = true)
    {
        $this->dryRun = (bool) $value;

        return $this;
    }

    public function enableBackup($value = true)
    {
        $this->enableBackup = (bool) $value;

        return $this;
    }
    
    public function allowNonDistFilesOverwrite($nonDistFilesOverwriteAllowed = true)
    {
        $this->nonDistFilesOverwriteAllowed = $nonDistFilesOverwriteAllowed;

        return $this;
    }

    public function setFormatterProvider(FormatterProvider $formatterProvider)
    {
        $this->formatterProvider = $formatterProvider;

        return $this;
    }

    public function setSystemEnvironment($environment)
    {
        $this->systemEnvironment = $environment;

        return $this;
    }

    public function hydrate($environment)
    {
        $files = $this->collectFiles();

        foreach($files as $file)
        {
            $this->hydrateFile($file, $environment);
        }

        $this->info(sprintf(
           '%d files generated',
            count($files)
        ));
    }

    private function collectFiles()
    {
        $pattern = sprintf('.*%s$', preg_quote($this->suffix));
        if($this->nonDistFilesOverwriteAllowed === true)
        {
            $pattern = '.*';
        }
        
        return $this->finder->findFiles(sprintf('~%s~', $pattern));
    }

    private function hydrateFile($file, $environment)
    {
        $this->currentTargetFile = preg_replace(sprintf('~(.*)(%s)$~', preg_quote($this->suffix)), '$1', $file);

        if($this->nonDistFilesOverwriteAllowed)
        {
            $this->currentTargetFile = (new \SplFileInfo($this->currentTargetFile))->getFilename();
        }

        $content = $this->sources->read($file);
        $replacementCounter = $this->parseFileDirectives($file, $content, $environment);

        $targetContent = $this->injectValues($file, $content, $environment, $replacementCounter);

        $this->debug("Write $this->currentTargetFile");
{'fraction_non_alphanumeric': 0.1317594302294909, 'fraction_numerical': 0.0007913479293062516, 'mean_word_length': 2.4704805491990847, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 93, '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': '3912361', 'n_tokens_mistral': 2211, 'n_tokens_neox': 2132, 'n_words': 379}