<commit_before><?php
    namespace PSFS\Services;

    use PSFS\base\Cache;
    use PSFS\base\config\Config;
    use PSFS\base\Service;

    class GeneratorService extends Service{
        /**
         * @Inyectable
         * @var \PSFS\base\config\Config Servicio de configuración
         */
        protected $config;
        /**
         * @Inyectable
         * @var \PSFS\base\Security Servicio de autenticación
         */
        protected $security;
        /**
         * @Inyectable
         * @var \PSFS\base\Template Servicio de gestión de plantillas
         */
        protected $tpl;

        /**
         * Método que revisa las traducciones directorio a directorio
         * @param $path
         * @param $locale
         * @return array
         */
        public static function findTranslations($path, $locale)
        {
            $locale_path = realpath(BASE_DIR . DIRECTORY_SEPARATOR . 'locale');
            $locale_path .= DIRECTORY_SEPARATOR . $locale . DIRECTORY_SEPARATOR . 'LC_MESSAGES' . DIRECTORY_SEPARATOR;

            $translations = array();
            if(file_exists($path))
            {
                $d = dir($path);
                while(false !== ($dir = $d->read()))
                {
                    Config::createDir($locale_path);
                    if(!file_exists($locale_path . 'translations.po')) {
                        file_put_contents($locale_path . 'translations.po', '');
                    }
                    $inspect_path = realpath($path.DIRECTORY_SEPARATOR.$dir);
                    $cmd_php = "export PATH=\$PATH:/opt/local/bin; xgettext ". $inspect_path . DIRECTORY_SEPARATOR ."*.php --from-code=UTF-8 -j -L PHP --debug --force-po -o {$locale_path}translations.po";
                    if(is_dir($path.DIRECTORY_SEPARATOR.$dir) && preg_match('/^\./',$dir) == 0)
                    {
                        $res = _('Revisando directorio: ') . $inspect_path;
                        $res .= _('Comando ejecutado: '). $cmd_php;
                        $res .= shell_exec($cmd_php);// . " >> " . __DIR__ . DIRECTORY_SEPARATOR . "debug.log 2>&1");
                        usleep(10);
                        $translations[] = $res;
                        $translations = array_merge($translations, self::findTranslations($inspect_path, $locale));
                    }
                }
            }
            return $translations;
        }

        /**
         * Servicio que genera la estructura de un módulo o lo actualiza en caso de ser necesario
         * @param string $module
         * @param boolean $force
         * @param string $type
         * @return mixed
         */
        public function createStructureModule($module, $force = false, $type = "")
        {
            $mod_path = CORE_DIR . DIRECTORY_SEPARATOR;
            $module = ucfirst($module);
            $this->createModulePath($module, $mod_path);
            $this->createModulePathTree($module, $mod_path);
            $this->createModuleBaseFiles($module, $mod_path, $force, $type);
            $this->createModuleModels($module);
            //Redireccionamos al home definido
            $this->log->infoLog("Módulo generado correctamente");
        }

        /**
         * Servicio que genera el path base del módulo
         * @param string $module
         * @param string $mod_path
         */
        private function createModulePath($module, $mod_path)
        {
            //Creamos el directorio base de los módulos
            Config::createDir($mod_path);
            //Creamos la carpeta del módulo
            Config::createDir($mod_path . $module);
        }

        /**
         * Servicio que genera la estructura base
         * @param $module
         * @param $mod_path
         */
        private function createModulePathTree($module, $mod_path)
        {
            //Creamos las carpetas CORE del módulo
            $this->log->infoLog("Generamos la estructura");
            $paths = array("Api", "Api/base", "Config", "Controller", "Form", "Models", "Public", "Templates", "Services", "Test");
            foreach($paths as $path) {
                Config::createDir($mod_path . $module . DIRECTORY_SEPARATOR . $path);
            }
            //Creamos las carpetas de los assets
            $htmlPaths = array("css", "js", "img", "media", "font");
            foreach($htmlPaths as $path) {
                Config::createDir($mod_path . $module . DIRECTORY_SEPARATOR . "Public" . DIRECTORY_SEPARATOR . $path);
            }
        }

        /**
         * Servicio que genera las plantillas básicas de ficheros del módulo
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @param string $controllerType
         */
        private function createModuleBaseFiles($module, $mod_path, $force = false, $controllerType = '')
        {
            $this->generateBaseApiTemplate($module, $mod_path);
            $this->generateControllerTemplate($module, $mod_path, $force, $controllerType);
            $this->generateServiceTemplate($module, $mod_path, $force);
            $this->genereateAutoloaderTemplate($module, $mod_path, $force);
            $this->generateSchemaTemplate($module, $mod_path, $force);
            $this->generatePropertiesTemplate($module, $mod_path, $force);
            $this->generateConfigTemplate($module, $mod_path, $force);
            $this->generateIndexTemplate($module, $mod_path, $force);
            $this->generatePublicTemplates($module, $mod_path, $force);
        }

        /**
         * Servicio que ejecuta Propel y genera el modelo de datos
         * @param string $module
         */
        private function createModuleModels($module)
        {
            //Generamos las clases de propel y la configuración
            $exec = "export PATH=\$PATH:/opt/local/bin; " . BASE_DIR . DIRECTORY_SEPARATOR . "vendor" . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "propel ";
            $schemaOpt = " --schema-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . "Config";
            $opt = " --config-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . "Config --output-dir=" . CORE_DIR . " --verbose";
            $ret = shell_exec($exec . "build" . $opt . $schemaOpt);

            $this->log->infoLog("Generamos clases invocando a propel:\n $ret");
            $ret = shell_exec($exec . "sql:build" . $opt . " --output-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . "Config" . $schemaOpt);
            $this->log->infoLog("Generamos sql invocando a propel:\n $ret");
            $ret = shell_exec($exec . "config:convert" . $opt . " --output-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . "Config");
            $this->log->infoLog("Generamos configuración invocando a propel:\n $ret");
        }

        /**
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @param string $controllerType
         * @return boolean
         */
        private function generateControllerTemplate($module, $mod_path, $force = false, $controllerType = "")
        {
            //Generamos el controlador base
            $this->log->infoLog("Generamos el controlador BASE");
            $controller = $this->tpl->dump("generator/controller.template.twig", array(
                "module" => $module,
                "controllerType" => $controllerType,
            ));
            return $this->writeTemplateToFile($controller, $mod_path . $module . DIRECTORY_SEPARATOR . "Controller" . DIRECTORY_SEPARATOR . "{$module}Controller.php", $force);
        }

        /**
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @param string $controllerType
         * @return boolean
         */
        private function generateBaseApiTemplate($module, $mod_path, $force = false, $controllerType = "")
        {
            //Generamos el controlador base
            $this->log->infoLog("Generamos Api BASES");
            $controller = $this->tpl->dump("generator/api.base.template.twig", array(
                "module" => $module,
                "controllerType" => $controllerType,
                "api" => "Test"
            ));
            $created = $this->writeTemplateToFile($controller, $mod_path . $module . DIRECTORY_SEPARATOR . "Api" . DIRECTORY_SEPARATOR . 'base' . DIRECTORY_SEPARATOR . "{$module}BaseApi.php", $force);
            $controller = $this->tpl->dump("generator/api.template.twig", array(
                "module" => $module,
                "controllerType" => $controllerType,
                "api" => "Test"
            ));
            $created = $this->writeTemplateToFile($controller, $mod_path . $module . DIRECTORY_SEPARATOR . "Api" . DIRECTORY_SEPARATOR . "{$module}.php", $force);
            return $created;
        }

        /**
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @return boolean
         */
        private function generateConfigTemplate($module, $mod_path, $force = false)
        {
            //Generamos el fichero de configuración
            $this->log->infoLog("Generamos fichero vacío de configuración");
            return $this->writeTemplateToFile("<?php\n\t", $mod_path . $module . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . "config.php", $force);
        }

        /**
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @return boolean
         */<commit_msg>Disabled test case for autogenerated api<commit_after><?php
    namespace PSFS\Services;

    use PSFS\base\Cache;
    use PSFS\base\config\Config;
    use PSFS\base\Service;

    class GeneratorService extends Service{
        /**
         * @Inyectable
         * @var \PSFS\base\config\Config Servicio de configuración
         */
        protected $config;
        /**
         * @Inyectable
         * @var \PSFS\base\Security Servicio de autenticación
         */
        protected $security;
        /**
         * @Inyectable
         * @var \PSFS\base\Template Servicio de gestión de plantillas
         */
        protected $tpl;

        /**
         * Método que revisa las traducciones directorio a directorio
         * @param $path
         * @param $locale
         * @return array
         */
        public static function findTranslations($path, $locale)
        {
            $locale_path = realpath(BASE_DIR . DIRECTORY_SEPARATOR . 'locale');
            $locale_path .= DIRECTORY_SEPARATOR . $locale . DIRECTORY_SEPARATOR . 'LC_MESSAGES' . DIRECTORY_SEPARATOR;

            $translations = array();
            if(file_exists($path))
            {
                $d = dir($path);
                while(false !== ($dir = $d->read()))
                {
                    Config::createDir($locale_path);
                    if(!file_exists($locale_path . 'translations.po')) {
                        file_put_contents($locale_path . 'translations.po', '');
                    }
                    $inspect_path = realpath($path.DIRECTORY_SEPARATOR.$dir);
                    $cmd_php = "export PATH=\$PATH:/opt/local/bin; xgettext ". $inspect_path . DIRECTORY_SEPARATOR ."*.php --from-code=UTF-8 -j -L PHP --debug --force-po -o {$locale_path}translations.po";
                    if(is_dir($path.DIRECTORY_SEPARATOR.$dir) && preg_match('/^\./',$dir) == 0)
                    {
                        $res = _('Revisando directorio: ') . $inspect_path;
                        $res .= _('Comando ejecutado: '). $cmd_php;
                        $res .= shell_exec($cmd_php);// . " >> " . __DIR__ . DIRECTORY_SEPARATOR . "debug.log 2>&1");
                        usleep(10);
                        $translations[] = $res;
                        $translations = array_merge($translations, self::findTranslations($inspect_path, $locale));
                    }
                }
            }
            return $translations;
        }

        /**
         * Servicio que genera la estructura de un módulo o lo actualiza en caso de ser necesario
         * @param string $module
         * @param boolean $force
         * @param string $type
         * @return mixed
         */
        public function createStructureModule($module, $force = false, $type = "")
        {
            $mod_path = CORE_DIR . DIRECTORY_SEPARATOR;
            $module = ucfirst($module);
            $this->createModulePath($module, $mod_path);
            $this->createModulePathTree($module, $mod_path);
            $this->createModuleBaseFiles($module, $mod_path, $force, $type);
            $this->createModuleModels($module);
            //Redireccionamos al home definido
            $this->log->infoLog("Módulo generado correctamente");
        }

        /**
         * Servicio que genera el path base del módulo
         * @param string $module
         * @param string $mod_path
         */
        private function createModulePath($module, $mod_path)
        {
            //Creamos el directorio base de los módulos
            Config::createDir($mod_path);
            //Creamos la carpeta del módulo
            Config::createDir($mod_path . $module);
        }

        /**
         * Servicio que genera la estructura base
         * @param $module
         * @param $mod_path
         */
        private function createModulePathTree($module, $mod_path)
        {
            //Creamos las carpetas CORE del módulo
            $this->log->infoLog("Generamos la estructura");
            $paths = array("Api", "Api/base", "Config", "Controller", "Form", "Models", "Public", "Templates", "Services", "Test");
            foreach($paths as $path) {
                Config::createDir($mod_path . $module . DIRECTORY_SEPARATOR . $path);
            }
            //Creamos las carpetas de los assets
            $htmlPaths = array("css", "js", "img", "media", "font");
            foreach($htmlPaths as $path) {
                Config::createDir($mod_path . $module . DIRECTORY_SEPARATOR . "Public" . DIRECTORY_SEPARATOR . $path);
            }
        }

        /**
         * Servicio que genera las plantillas básicas de ficheros del módulo
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @param string $controllerType
         */
        private function createModuleBaseFiles($module, $mod_path, $force = false, $controllerType = '')
        {
            $this->generateBaseApiTemplate($module, $mod_path);
            $this->generateControllerTemplate($module, $mod_path, $force, $controllerType);
            $this->generateServiceTemplate($module, $mod_path, $force);
            $this->genereateAutoloaderTemplate($module, $mod_path, $force);
            $this->generateSchemaTemplate($module, $mod_path, $force);
            $this->generatePropertiesTemplate($module, $mod_path, $force);
            $this->generateConfigTemplate($module, $mod_path, $force);
            $this->generateIndexTemplate($module, $mod_path, $force);
            $this->generatePublicTemplates($module, $mod_path, $force);
        }

        /**
         * Servicio que ejecuta Propel y genera el modelo de datos
         * @param string $module
         */
        private function createModuleModels($module)
        {
            //Generamos las clases de propel y la configuración
            $exec = "export PATH=\$PATH:/opt/local/bin; " . BASE_DIR . DIRECTORY_SEPARATOR . "vendor" . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "propel ";
            $schemaOpt = " --schema-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . "Config";
            $opt = " --config-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . "Config --output-dir=" . CORE_DIR . " --verbose";
            $ret = shell_exec($exec . "build" . $opt . $schemaOpt);

            $this->log->infoLog("Generamos clases invocando a propel:\n $ret");
            $ret = shell_exec($exec . "sql:build" . $opt . " --output-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . "Config" . $schemaOpt);
            $this->log->infoLog("Generamos sql invocando a propel:\n $ret");
            $ret = shell_exec($exec . "config:convert" . $opt . " --output-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . "Config");
            $this->log->infoLog("Generamos configuración invocando a propel:\n $ret");
        }

        /**
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @param string $controllerType
         * @return boolean
         */
        private function generateControllerTemplate($module, $mod_path, $force = false, $controllerType = "")
        {
            //Generamos el controlador base
            $this->log->infoLog("Generamos el controlador BASE");
            $controller = $this->tpl->dump("generator/controller.template.twig", array(
                "module" => $module,
                "controllerType" => $controllerType,
            ));
            return $this->writeTemplateToFile($controller, $mod_path . $module . DIRECTORY_SEPARATOR . "Controller" . DIRECTORY_SEPARATOR . "{$module}Controller.php", $force);
        }

        /**
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @param string $controllerType
         * @return boolean
         */
        private function generateBaseApiTemplate($module, $mod_path, $force = false, $controllerType = "")
        {
            $created = true;
            if (false)
            {
                //Generamos el controlador base
                $this->log->infoLog("Generamos Api BASES");
                $controller = $this->tpl->dump("generator/api.base.template.twig", array(
                    "module" => $module,
                    "controllerType" => $controllerType,
                    "api" => "Test"
                ));
                $created = $this->writeTemplateToFile($controller, $mod_path . $module . DIRECTORY_SEPARATOR . "Api" . DIRECTORY_SEPARATOR . 'base' . DIRECTORY_SEPARATOR . "{$module}BaseApi.php", $force);
                $controller = $this->tpl->dump("generator/api.template.twig", array(
                    "module" => $module,
                    "controllerType" => $controllerType,
                    "api" => "Test"
                ));
                $created = $this->writeTemplateToFile($controller, $mod_path . $module . DIRECTORY_SEPARATOR . "Api" . DIRECTORY_SEPARATOR . "{$module}.php", $force);
            }
            return $created;
        }

        /**
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @return boolean
         */
        private function generateConfigTemplate($module, $mod_path, $force = false)
        {
            //Generamos el fichero de configuración
            $this->log->infoLog("Generamos fichero vacío de configuración");
            return $this->writeTemplateToFile("<?php\n\t", $mod_path . $module . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . "config.php", $force);
        }

        /**
         * @param string $module
         * @param string $mod_path
         * @param boolean $force
         * @return boolean
         */
{'fraction_non_alphanumeric': 0.12797664771854356, 'fraction_numerical': 0.0006145337225380243, 'mean_word_length': 1.879811237280637, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 105, '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': '5981364', 'n_tokens_mistral': 5530, 'n_tokens_neox': 5374, 'n_words': 1177}