<commit_before><?php namespace Aedart\Scaffold\Indexes;

use Aedart\Laravel\Helpers\Traits\Filesystem\FileTrait;
use Aedart\Scaffold\Traits\IndexDirectoryPath;
use Carbon\Carbon;
use Illuminate\Support\Str;

/**
 * Index Builder
 *
 * @TODO ... description, interface maybe?
 *
 * @author <NAME> <<EMAIL>>
 * @package Aedart\Scaffold\Indexes
 */
class IndexBuilder
{
    use FileTrait;
    use IndexDirectoryPath;

    /**
     * Name of the directory where
     * this index file is going to
     * be located
     */
    const SCAFFOLD_INDEX_DIRECTORY_NAME = '.scaffold/';

    /**
     * Scaffold file name pattern
     */
    const SCAFFOLD_FILE_PATTERN = '*.scaffold.php';

    /**
     * The index content
     *
     * @var array
     */
    protected $index = [];

    /**
     * Locations where to search for
     * scaffold files
     *
     * @var array
     */
    protected $placesToSearch = [];

    /**
     * IndexBuilder constructor.
     */
    public function __construct()
    {
        $this->placesToSearch = [
            getcwd() . DIRECTORY_SEPARATOR,
            // TODO: vendor path, ==> $composerConfig = \Composer\Factory::createConfig(null, getcwd());
            // TODO: global vendor path
        ];
    }

    /**
     * Searches and generates an index file of all the found
     * scaffold configuration files
     */
    public function build()
    {
        // TODO: $force option
        // TODO: do we really need to build - check if exists and if expired...

        // Create scaffold directory if not already exists
        $this->makeIndexDirectory();

        // Git ignore the index directory path
        $this->gitIgnoreIndexDirectory();

        // Search for scaffold files and add them to the index
        foreach($this->placesToSearch as $path){
            $this->index($path);
        }

        // Build the index file
        $this->buildIndexFile($this->index);
    }

    /**
     * Searches for scaffold files in the given path and
     * adds them to the index - if any found!
     *
     * @param string $path
     */
    protected function index($path)
    {
        $fs = $this->getFile();

        // Search for *.scaffold.php files
        $scaffolds = $fs->glob( $path . self::SCAFFOLD_FILE_PATTERN);

        // Abort if nothing found
        if(empty($scaffolds)){
            // TODO: output if nothing found
            return;
        }

        // Add each scaffold to the index
        foreach($scaffolds as $scaffoldFile){
            $this->addScaffoldFileToIndex($scaffoldFile);
        }
    }

    /**
     * Add the given scaffold configuration file to the index
     *
     * @param string $file Scaffold configuration file
     *
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
     */
    protected function addScaffoldFileToIndex($file)
    {
        $fs = $this->getFile();

        // Load the scaffold file
        $scaffold = $this->loadScaffoldFile($file);

        // Get the name and desc. of the scaffold
        $scaffoldName = $scaffold['name'];
        $scaffoldDescription = $scaffold['description'];

        // Default Package vendor and package name
        $packageVendor = '(no vendor)';
        $packageName = '(no package name)';

        // Set vendor and package from composer file, if available
        $composerFile = $fs->dirname($file) . DIRECTORY_SEPARATOR . 'composer.json';
        if($fs->exists($composerFile)){
            $packageComposer = json_decode($fs->get($composerFile), true);
            $parts = explode('/', $packageComposer['name']);

            $packageVendor = $parts[0];
            $packageName = $parts[1];
        }

        // Add to index
        $this->index[$packageVendor][$packageName][] = [
            'name'          => $scaffoldName,
            'description'   => $scaffoldDescription,
            'file'          => $file
        ];
    }

    /**
     * Persists the content given into an index file
     *
     * Previous index file will be removed before new
     * index file is saved to the disk
     *
     * @param array $content
     */
    protected function buildIndexFile(array $content)
    {
        $fs = $this->getFile();

        // Add expires date
        $index['expiresAt'] = (string) Carbon::now()->addMinutes(30);

        // Path of the index file
        // TODO: ... uhm, name of the index file...
        $indexFile = $this->getIndexDirectoryPath() . 'index.json';

        // Clear any eventual previous index file
        if($fs->exists($indexFile)){
            $fs->delete($indexFile);
        }

        // Write the index file
        $fs->append($indexFile, json_encode($content, JSON_PRETTY_PRINT));<commit_msg>Fix expires at not set in index file<commit_after><?php namespace Aedart\Scaffold\Indexes;

use Aedart\Laravel\Helpers\Traits\Filesystem\FileTrait;
use Aedart\Scaffold\Traits\IndexDirectoryPath;
use Carbon\Carbon;
use Illuminate\Support\Str;

/**
 * Index Builder
 *
 * @TODO ... description, interface maybe?
 *
 * @author <NAME> <<EMAIL>>
 * @package Aedart\Scaffold\Indexes
 */
class IndexBuilder
{
    use FileTrait;
    use IndexDirectoryPath;

    /**
     * Name of the directory where
     * this index file is going to
     * be located
     */
    const SCAFFOLD_INDEX_DIRECTORY_NAME = '.scaffold/';

    /**
     * Scaffold file name pattern
     */
    const SCAFFOLD_FILE_PATTERN = '*.scaffold.php';

    /**
     * The index content
     *
     * @var array
     */
    protected $index = [];

    /**
     * Locations where to search for
     * scaffold files
     *
     * @var array
     */
    protected $placesToSearch = [];

    /**
     * IndexBuilder constructor.
     */
    public function __construct()
    {
        $this->placesToSearch = [
            getcwd() . DIRECTORY_SEPARATOR,
            // TODO: vendor path, ==> $composerConfig = \Composer\Factory::createConfig(null, getcwd());
            // TODO: global vendor path
        ];
    }

    /**
     * Searches and generates an index file of all the found
     * scaffold configuration files
     */
    public function build()
    {
        // TODO: $force option
        // TODO: do we really need to build - check if exists and if expired...

        // Create scaffold directory if not already exists
        $this->makeIndexDirectory();

        // Git ignore the index directory path
        $this->gitIgnoreIndexDirectory();

        // Search for scaffold files and add them to the index
        foreach($this->placesToSearch as $path){
            $this->index($path);
        }

        // Build the index file
        $this->buildIndexFile($this->index);
    }

    /**
     * Searches for scaffold files in the given path and
     * adds them to the index - if any found!
     *
     * @param string $path
     */
    protected function index($path)
    {
        $fs = $this->getFile();

        // Search for *.scaffold.php files
        $scaffolds = $fs->glob( $path . self::SCAFFOLD_FILE_PATTERN);

        // Abort if nothing found
        if(empty($scaffolds)){
            // TODO: output if nothing found
            return;
        }

        // Add each scaffold to the index
        foreach($scaffolds as $scaffoldFile){
            $this->addScaffoldFileToIndex($scaffoldFile);
        }
    }

    /**
     * Add the given scaffold configuration file to the index
     *
     * @param string $file Scaffold configuration file
     *
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
     */
    protected function addScaffoldFileToIndex($file)
    {
        $fs = $this->getFile();

        // Load the scaffold file
        $scaffold = $this->loadScaffoldFile($file);

        // Get the name and desc. of the scaffold
        $scaffoldName = $scaffold['name'];
        $scaffoldDescription = $scaffold['description'];

        // Default Package vendor and package name
        $packageVendor = '(no vendor)';
        $packageName = '(no package name)';

        // Set vendor and package from composer file, if available
        $composerFile = $fs->dirname($file) . DIRECTORY_SEPARATOR . 'composer.json';
        if($fs->exists($composerFile)){
            $packageComposer = json_decode($fs->get($composerFile), true);
            $parts = explode('/', $packageComposer['name']);

            $packageVendor = $parts[0];
            $packageName = $parts[1];
        }

        // Add to index
        $this->index[$packageVendor][$packageName][] = [
            'name'          => $scaffoldName,
            'description'   => $scaffoldDescription,
            'file'          => $file
        ];
    }

    /**
     * Persists the content given into an index file
     *
     * Previous index file will be removed before new
     * index file is saved to the disk
     *
     * @param array $content
     */
    protected function buildIndexFile(array $content)
    {
        $fs = $this->getFile();

        // Add expires date
        $content['expiresAt'] = (string) Carbon::now()->addMinutes(30);

        // Path of the index file
        // TODO: ... uhm, name of the index file...
        $indexFile = $this->getIndexDirectoryPath() . 'index.json';

        // Clear any eventual previous index file
        if($fs->exists($indexFile)){
            $fs->delete($indexFile);
        }

        // Write the index file
        $fs->append($indexFile, json_encode($content, JSON_PRETTY_PRINT));
{'fraction_non_alphanumeric': 0.11977568511268649, 'fraction_numerical': 0.0008464712728811766, 'mean_word_length': 2.0121096239643084, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 61, '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': '1436448', 'n_tokens_mistral': 2753, 'n_tokens_neox': 2643, 'n_words': 730}