<commit_before><?php
/**
 * File for Application class
 */

namespace Cayman;

use Manager\AssetManager;
use Manager\CacheManager;
use Manager\DbManager;
use Manager\DbSchemaManager;
use Manager\EmailManager;
use Manager\EmailManager\Email;
use Manager\EntityManager;
use Manager\EventManager;
use Manager\EventManager\EventContext;
use Manager\FilterManager;
use Manager\IdentityManager;
use Manager\LocaleManager;
use Manager\LogManager;
use Manager\QueueManager;
use Manager\ReleaseManager;

/**
 * Abstract class for Application
 * 
 * @method \PDO             getPdoManager($id = 'default')
 * @method \Redis           getRedisManager($id = 'default')
 * 
 * @method AssetManager     getAssetManager($id = 'default')
 * @method CacheManager     getCacheManager($id = 'default')
 * @method DbManager        getDbManager($id = 'default')
 * @method DbSchemaManager  getDbSchemaManager($id = 'default')
 * @method EmailManager     getEmailManager($id = 'default')
 * @method EntityManager    getEntityManager($id = 'default')
 * @method EventManager     getEventManager($id = 'default')
 * @method FilterManager    getFilterManager($id = 'default')
 * @method IdentityManager  getIdentityManager($id = 'default')
 * @method LocaleManager    getLocaleManager($id = 'default')
 * @method LogManager       getLogManager($id = 'default')
 * @method QueueManager     getQueueManager($id = 'default')
 * @method ReleaseManager   getReleaseManager($id = 'default')
 * 
 */
abstract class Application
{
    use SettingsTrait;
    
    /**
     * Array of managers loaded
     * @var Manager[]
     */
    private $managers = [];
    
    /**
     * Array of services loaded
     * @var Service[]
     */
    private $services = [];
    
    /**
     * Magic call handler
     * @param string $name
     * @param array  $arguments
     * @return Manager
     */
    function __call($name, $arguments)
    {
        $result = null;
        
        if ('get' == substr($name, 0, 3)) {
            $type   = strtolower(substr($name, 3));
            
            if (stripos($type, 'manager') !== false) {
                $type   = str_replace('manager', '', $type);
                $id     = isset($arguments[0]) ? $arguments[0] : 'default';
                $result = $this->getManager($type, $id);
            }
            if (stripos($type, 'service') !== false) {
                $type   = str_replace('service', '', $type);
                $id     = isset($arguments[0]) ? $arguments[0] : 'default';
                $result = $this->getService($type, $id);
            }
        }
        
        return $result;
    }
    
    /**
     * Load manager
     * @param string $type
     * @param string $id
     * @return Manager
     * @throws Exception
     */
    function loadManager($type, $id = 'default')
    {
        $typeOriginal = $type;
        $type = strtolower($type);
        $managersArr = $this->getSettings()->getEntry('managers');
        if (empty($managersArr[$type])) {
            throw new Exception('Manager setting undefined type: ' . $type . ' id: ' . $id);
        }
        if (empty($managersArr[$type][$id])) {
            throw new Exception('Manager setting undefined type: ' . $type . ' id: ' . $id);
        }
        
        $managerArr  = $managersArr[$type][$id];
        if (empty($managerArr['factory']) or ! is_callable($managerArr['factory'])) {
            throw new Exception('Manager factory undefined type: ' . $type . ' id: ' . $id);
        }
        $factory    = $managerArr['factory'];
        $settingArr = isset($managerArr['settings']) ? $managerArr['settings'] : [];
        $settings   = new Settings($settingArr);
        $params     = [$this, $settings, $id];
        $manager    = call_user_func_array($factory, $params);// run manager factory * * *
        //if (!($manager instanceof Manager)) {
        //    throw new Exception('Invalid manager implementation: ' . $typeOriginal);
        //}
        $this->setManager($manager, $type, $id);
        
        return $manager;
    }
    
    /**
     * Set manager
     * @param Manager $manager
     * @param string  $type
     * @param string  $id
     * @return void
     */
    function setManager(Manager $manager, $type, $id)
    {
        $this->managers[$type][$id] = $manager;
    }
    
    /**
     * Get manager
     * @param string $type
     * @param string $id
     * @return Manager
     * @throws Exception
     */
    function getManager($type, $id = 'default')
    {
        if (empty($this->managers[$type][$id])) {
            $this->loadManager($type, $id);<commit_msg>making it flexible for manager storage<commit_after><?php
/**
 * File for Application class
 */

namespace Cayman;

use Manager\AssetManager;
use Manager\CacheManager;
use Manager\DbManager;
use Manager\DbSchemaManager;
use Manager\EmailManager;
use Manager\EmailManager\Email;
use Manager\EntityManager;
use Manager\EventManager;
use Manager\EventManager\EventContext;
use Manager\FilterManager;
use Manager\IdentityManager;
use Manager\LocaleManager;
use Manager\LogManager;
use Manager\QueueManager;
use Manager\ReleaseManager;

/**
 * Abstract class for Application
 * 
 * @method \PDO             getPdoManager($id = 'default')
 * @method \Redis           getRedisManager($id = 'default')
 * 
 * @method AssetManager     getAssetManager($id = 'default')
 * @method CacheManager     getCacheManager($id = 'default')
 * @method DbManager        getDbManager($id = 'default')
 * @method DbSchemaManager  getDbSchemaManager($id = 'default')
 * @method EmailManager     getEmailManager($id = 'default')
 * @method EntityManager    getEntityManager($id = 'default')
 * @method EventManager     getEventManager($id = 'default')
 * @method FilterManager    getFilterManager($id = 'default')
 * @method IdentityManager  getIdentityManager($id = 'default')
 * @method LocaleManager    getLocaleManager($id = 'default')
 * @method LogManager       getLogManager($id = 'default')
 * @method QueueManager     getQueueManager($id = 'default')
 * @method ReleaseManager   getReleaseManager($id = 'default')
 * 
 */
abstract class Application
{
    use SettingsTrait;
    
    /**
     * Array of managers loaded
     * @var Manager[]
     */
    private $managers = [];
    
    /**
     * Array of services loaded
     * @var Service[]
     */
    private $services = [];
    
    /**
     * Magic call handler
     * @param string $name
     * @param array  $arguments
     * @return Manager
     */
    function __call($name, $arguments)
    {
        $result = null;
        
        if ('get' == substr($name, 0, 3)) {
            $type   = strtolower(substr($name, 3));
            
            if (stripos($type, 'manager') !== false) {
                $type   = str_replace('manager', '', $type);
                $id     = isset($arguments[0]) ? $arguments[0] : 'default';
                $result = $this->getManager($type, $id);
            }
            if (stripos($type, 'service') !== false) {
                $type   = str_replace('service', '', $type);
                $id     = isset($arguments[0]) ? $arguments[0] : 'default';
                $result = $this->getService($type, $id);
            }
        }
        
        return $result;
    }
    
    /**
     * Load manager
     * @param string $type
     * @param string $id
     * @return Manager
     * @throws Exception
     */
    function loadManager($type, $id = 'default')
    {
        $typeOriginal = $type;
        $type = strtolower($type);
        $managersArr = $this->getSettings()->getEntry('managers');
        if (empty($managersArr[$type])) {
            throw new Exception('Manager setting undefined type: ' . $type . ' id: ' . $id);
        }
        if (empty($managersArr[$type][$id])) {
            throw new Exception('Manager setting undefined type: ' . $type . ' id: ' . $id);
        }
        
        $managerArr  = $managersArr[$type][$id];
        if (empty($managerArr['factory']) or ! is_callable($managerArr['factory'])) {
            throw new Exception('Manager factory undefined type: ' . $type . ' id: ' . $id);
        }
        $factory    = $managerArr['factory'];
        $settingArr = isset($managerArr['settings']) ? $managerArr['settings'] : [];
        $settings   = new Settings($settingArr);
        $params     = [$this, $settings, $id];
        $manager    = call_user_func_array($factory, $params);// run manager factory * * *
        //if (!($manager instanceof Manager)) {
        //    throw new Exception('Invalid manager implementation: ' . $typeOriginal);
        //}
        $this->setManager($manager, $type, $id);
        
        return $manager;
    }
    
    /**
     * Set manager
     * @param Manager $manager
     * @param string  $type
     * @param string  $id
     * @return void
     */
    function setManager($manager, $type, $id)
    {
        $this->managers[$type][$id] = $manager;
    }
    
    /**
     * Get manager
     * @param string $type
     * @param string $id
     * @return Manager
     * @throws Exception
     */
    function getManager($type, $id = 'default')
    {
        if (empty($this->managers[$type][$id])) {
            $this->loadManager($type, $id);
{'fraction_non_alphanumeric': 0.1471194531843333, 'fraction_numerical': 0.001518932407507866, 'mean_word_length': 2.3556607207863123, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, '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': '784814', 'n_tokens_mistral': 2632, 'n_tokens_neox': 2605, 'n_words': 619}