<commit_before><?php
namespace Tuum\Builder;

/**
 * Class AppBuilder
 *
 * a generic application builder for environment aware process.
 *
 * @package WScore\Site\Builder
 */
class AppBuilder
{
    use SettingTrait;
    
    /**
     * @var mixed       the application to configure
     */
    public $app = null;

    /**
     * @var string      main config dir (ex: project-root/app/)
     */
    public $app_dir;

    /**
     * @var string      var dir (no version control) (ex: project-root/vars)
     */
    public $var_dir;

    /**
     * @var bool        debug or not
     */
    public $debug = false;

    /**
     * @var Environment
     */
    private $envObj;

    /**
     * @param string           $app_dir
     * @param string|null      $var_dir
     * @param null|Environment $env
     */
    public function __construct($app_dir, $var_dir = null, $env = null)
    {
        $this->app_dir = $app_dir;
        $this->var_dir = $var_dir;
        $this->envObj  = $env ?: new Environment();
    }

    /**
     * forges AppBuilder.
     *
     * $options = array(
     *   'env'      => 'env-name',  // or array of env-names.
     *   'debug'    => true,      // or false.
     *   'env-file' => 'env-file-name',
     * )
     *
     * @param string      $app_dir
     * @param string|null $var_dir
     * @param array       $options
     * @return AppBuilder
     */
    public static function forge($app_dir, $var_dir = null, $options=[])
    {
        $builder = new self($app_dir, $var_dir);
        if (isset($options['env'])) {
            $builder->envObj->setEnvironment((array) $options['env']);
        }
        if (isset($options['debug'])) {
            $builder->debug = $options['debug'];
        }
        if (isset($options['env-file'])) {
            $builder->loadEnvironment($options['env-file']);
        }
        $options['app-dir'] = $app_dir;
        $options['var-dir'] = $var_dir;
        $builder->set('options', $options);
        return $builder;
    }

    /**
     * read the configuration script at $this->app_dir/{$env/}$file.
     *
     * if environment, $env, is defined, read the scripts for the
     * environment, and terminate the loop.
     *
     * if no environment scripts are found, read the production
     * (i.e. no $env/) script.
     *
     * if the env-specific script depends on the production script,
     * read the production script inside env-specific script, as
     * $builder->execute(__DIR__ . '/../your-scripts');
     *
     * @api
     * @param string $config
     * @return $this
     */
    public function configure($config)
    {
        $directory = $this->app_dir . DIRECTORY_SEPARATOR;
        $list_env  = array_reverse($this->envObj->listEnvironments(['']));
        foreach ($list_env as $env) {
            $file = ($env ? $env . DIRECTORY_SEPARATOR : '') . $config;
            if ($this->execute($directory . $file) !== false) {
                return $this;
            }
        }

        return $this;
    }

    /**
     * evaluate PHP file ($__file.php) and returns the value.
     * the file path must be an absolute path.
     *
     * if a callable is returned from the script, builder
     * will execute the callable with $this as an argument.
     *
     * @api
     * @param string $__file
     * @return mixed|bool
     */
    public function execute($__file)
    {
        $__file = $__file . '.php';
        if (!file_exists($__file)) {
            return false;
        }
        /** @noinspection PhpUnusedLocalVariableInspection */
        $app = $this->app;
        /** @noinspection PhpUnusedLocalVariableInspection */
        $builder = $this;

        /** @noinspection PhpIncludeInspection */

        $returned = include($__file);
        if (is_callable($returned)) {
            $returned = call_user_func($returned, $this);
        }
        return $returned;<commit_msg>configure to return whatever returned by the configuration script.<commit_after><?php
namespace Tuum\Builder;

/**
 * Class AppBuilder
 *
 * a generic application builder for environment aware process.
 *
 * @package WScore\Site\Builder
 */
class AppBuilder
{
    use SettingTrait;
    
    /**
     * @var mixed       the application to configure
     */
    public $app = null;

    /**
     * @var string      main config dir (ex: project-root/app/)
     */
    public $app_dir;

    /**
     * @var string      var dir (no version control) (ex: project-root/vars)
     */
    public $var_dir;

    /**
     * @var bool        debug or not
     */
    public $debug = false;

    /**
     * @var Environment
     */
    private $envObj;

    /**
     * @param string           $app_dir
     * @param string|null      $var_dir
     * @param null|Environment $env
     */
    public function __construct($app_dir, $var_dir = null, $env = null)
    {
        $this->app_dir = $app_dir;
        $this->var_dir = $var_dir;
        $this->envObj  = $env ?: new Environment();
    }

    /**
     * forges AppBuilder.
     *
     * $options = array(
     *   'env'      => 'env-name',  // or array of env-names.
     *   'debug'    => true,      // or false.
     *   'env-file' => 'env-file-name',
     * )
     *
     * @param string      $app_dir
     * @param string|null $var_dir
     * @param array       $options
     * @return AppBuilder
     */
    public static function forge($app_dir, $var_dir = null, $options=[])
    {
        $builder = new self($app_dir, $var_dir);
        if (isset($options['env'])) {
            $builder->envObj->setEnvironment((array) $options['env']);
        }
        if (isset($options['debug'])) {
            $builder->debug = $options['debug'];
        }
        if (isset($options['env-file'])) {
            $builder->loadEnvironment($options['env-file']);
        }
        $options['app-dir'] = $app_dir;
        $options['var-dir'] = $var_dir;
        $builder->set('options', $options);
        return $builder;
    }

    /**
     * read the configuration script at $this->app_dir/{$env/}$file.
     *
     * if no environment scripts are found, read the production
     * (i.e. no $env/) script.
     *
     * if an environment, $env, is defined, read the scripts for the
     * environment, and terminate the loop. if no env-specific
     * scripts are found, reads the production script.
     *
     * if the env-specific script depends on the production script,
     * read the production script inside env-specific script, as
     * $builder->execute(__DIR__ . '/../your-scripts.php');
     *
     * @api
     * @param string $config
     * @return $this|mixed
     */
    public function configure($config)
    {
        $directory = $this->app_dir . DIRECTORY_SEPARATOR;
        $list_env  = array_reverse($this->envObj->listEnvironments(['']));
        foreach ($list_env as $env) {
            $file = $directory . ($env ? $env . DIRECTORY_SEPARATOR : '') . $config . '.php';
            if (file_exists($file)) {
                return $this->execute($file);
            }
        }

        return $this;
    }

    /**
     * evaluate PHP file ($__file.php) and returns the value.
     * the file path must be an absolute path.
     *
     * if a callable is returned from the script, builder
     * will execute the callable with $this as an argument.
     *
     * @api
     * @param string $__file
     * @return mixed|bool
     */
    public function execute($__file)
    {
        if (substr($__file, -4) !== '.php' ) {
            $__file = $__file . '.php';
        }
        if (!file_exists($__file)) {
            return false;
        }
        /** @noinspection PhpUnusedLocalVariableInspection */
        $app = $this->app;
        /** @noinspection PhpUnusedLocalVariableInspection */
        $builder = $this;

        /** @noinspection PhpIncludeInspection */

        $returned = include($__file);
        if (is_callable($returned)) {
            $returned = call_user_func($returned, $this);
        }
        return $returned;
{'fraction_non_alphanumeric': 0.14014251781472684, 'fraction_numerical': 0.00012501562695336918, 'mean_word_length': 1.9112081513828238, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 39, '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': '4509516', 'n_tokens_mistral': 2421, 'n_tokens_neox': 2390, 'n_words': 610}