<commit_before><?php

namespace RMiller\ExemplifyExtension\Generator;

use PhpSpec\CodeGenerator\Generator\GeneratorInterface;
use PhpSpec\Console\IO;
use PhpSpec\CodeGenerator\TemplateRenderer;
use PhpSpec\Util\Filesystem;
use PhpSpec\Locator\ResourceInterface;
use RMiller\Caser\Cased;

/**
 * Generates class methods from a resource
 */
class SpecificationMethodGenerator implements GeneratorInterface
{
    /**
     * @var \PhpSpec\Console\IO
     */
    private $io;

    /**
     * @var \PhpSpec\CodeGenerator\TemplateRenderer
     */
    private $templates;

    /**
     * @var \PhpSpec\Util\Filesystem
     */
    private $filesystem;

    /**
     * @param IO               $io
     * @param TemplateRenderer $templates
     * @param Filesystem       $filesystem
     */
    public function __construct(IO $io, TemplateRenderer $templates, Filesystem $filesystem = null)
    {
        $this->io         = $io;
        $this->templates  = $templates;
        $this->filesystem = $filesystem ?: new Filesystem();
    }

    /**
     * @param ResourceInterface $resource
     * @param string            $generation
     * @param array             $data
     *
     * @return bool
     */
    public function supports(ResourceInterface $resource, $generation, array $data)
    {
        return 'specification_method' === $generation;
    }

    /**
     * @param ResourceInterface $resource
     * @param array             $data
     */
    public function generate(ResourceInterface $resource, array $data = [])
    {
        $method = Cased::fromCamelCase($data['method']);
        $spec = $this->filesystem->getFileContents($resource->getSpecFilename());

        if ($this->exampleAlreadyExists($spec, $method)) {
            $this->informExampleAlreadyExists($resource, $method);

            return;
        }

        $this->addExampleToSpec($resource, $spec, $method, $data['type']);
    }

    /**
     * @return int
     */
    public function getPriority()
    {
        return 0;
    }

    /**
     * @param $type
     * @return string
     */
    protected function getTemplate($type)
    {
        return file_get_contents(__DIR__.'/templates/'.$type.'.template');
    }

    /**
     * @param $spec
     * @param \RMiller\Caser\Cased $method
     * @return bool
     */
    private function exampleAlreadyExists($spec, Cased $method)
    {
        $camelCaseMethod = $method->asCamelCase();

        $methodStrings = [
            '$this->' . $camelCaseMethod . '(',
            '$this::' . $camelCaseMethod . '(',
            '$this->beConstructedThrough(\'' . $camelCaseMethod . '\'',
        ];

        foreach ($methodStrings as $existingMethodString) {
            if (strpos($spec, $existingMethodString) !== false) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param \RMiller\Caser\Cased $method
     * @param $type
     * @return string
     */
    private function renderContent(Cased $method, $type)
    {
        return $this->templates->renderString($this->getTemplate($type), [
            '%method%' => $method->asCamelCase(),
            '%example_name%' => 'it_should_' . $method->asSnakeCase(),
            '%constructor_example_name%' => 'it_should_be_constructed_through_' . $method->asSnakeCase(),
        ]);
    }

    /**
     * @param \PhpSpec\Locator\ResourceInterface $resource
     * @param $spec
     * @param \RMiller\Caser\Cased $method<commit_msg>Scrutinizer Auto-Fixes<commit_after><?php

namespace RMiller\ExemplifyExtension\Generator;

use PhpSpec\CodeGenerator\Generator\GeneratorInterface;
use PhpSpec\Console\IO;
use PhpSpec\CodeGenerator\TemplateRenderer;
use PhpSpec\Util\Filesystem;
use PhpSpec\Locator\ResourceInterface;
use RMiller\Caser\Cased;

/**
 * Generates class methods from a resource
 */
class SpecificationMethodGenerator implements GeneratorInterface
{
    /**
     * @var \PhpSpec\Console\IO
     */
    private $io;

    /**
     * @var \PhpSpec\CodeGenerator\TemplateRenderer
     */
    private $templates;

    /**
     * @var \PhpSpec\Util\Filesystem
     */
    private $filesystem;

    /**
     * @param IO               $io
     * @param TemplateRenderer $templates
     * @param Filesystem       $filesystem
     */
    public function __construct(IO $io, TemplateRenderer $templates, Filesystem $filesystem = null)
    {
        $this->io         = $io;
        $this->templates  = $templates;
        $this->filesystem = $filesystem ?: new Filesystem();
    }

    /**
     * @param ResourceInterface $resource
     * @param string            $generation
     * @param array             $data
     *
     * @return bool
     */
    public function supports(ResourceInterface $resource, $generation, array $data)
    {
        return 'specification_method' === $generation;
    }

    /**
     * @param ResourceInterface $resource
     * @param array             $data
     */
    public function generate(ResourceInterface $resource, array $data = [])
    {
        $method = Cased::fromCamelCase($data['method']);
        $spec = $this->filesystem->getFileContents($resource->getSpecFilename());

        if ($this->exampleAlreadyExists($spec, $method)) {
            $this->informExampleAlreadyExists($resource, $method);

            return;
        }

        $this->addExampleToSpec($resource, $spec, $method, $data['type']);
    }

    /**
     * @return int
     */
    public function getPriority()
    {
        return 0;
    }

    /**
     * @param $type
     * @return string
     */
    protected function getTemplate($type)
    {
        return file_get_contents(__DIR__.'/templates/'.$type.'.template');
    }

    /**
     * @param string $spec
     * @param \RMiller\Caser\Cased $method
     * @return bool
     */
    private function exampleAlreadyExists($spec, Cased $method)
    {
        $camelCaseMethod = $method->asCamelCase();

        $methodStrings = [
            '$this->' . $camelCaseMethod . '(',
            '$this::' . $camelCaseMethod . '(',
            '$this->beConstructedThrough(\'' . $camelCaseMethod . '\'',
        ];

        foreach ($methodStrings as $existingMethodString) {
            if (strpos($spec, $existingMethodString) !== false) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param \RMiller\Caser\Cased $method
     * @param $type
     * @return string
     */
    private function renderContent(Cased $method, $type)
    {
        return $this->templates->renderString($this->getTemplate($type), [
            '%method%' => $method->asCamelCase(),
            '%example_name%' => 'it_should_' . $method->asSnakeCase(),
            '%constructor_example_name%' => 'it_should_be_constructed_through_' . $method->asSnakeCase(),
        ]);
    }

    /**
     * @param \PhpSpec\Locator\ResourceInterface $resource
     * @param string $spec
     * @param \RMiller\Caser\Cased $method
{'fraction_non_alphanumeric': 0.13655371304974764, 'fraction_numerical': 0.00028839221341023794, 'mean_word_length': 2.2335664335664336, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 45, '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': '5442805', 'n_tokens_mistral': 2041, 'n_tokens_neox': 1993, 'n_words': 380}