<?php
$MIOLO->uses( 'classes/bSync.interface.php','base');
$MIOLO->uses( 'classes/bSyncDatabase.class.php','base');
$MIOLO->uses( 'classes/bSyncDatabaseContent.class.php','base');
$MIOLO->uses( 'classes/bSyncDatabaseFunction.class.php','base');
$MIOLO->uses( 'classes/bSyncDatabaseView.class.php','base');
$MIOLO->uses( 'classes/bSyncDatabaseDependencies.class.php','base');
$MIOLO->uses( 'classes/BString.class.php','base');
$MIOLO->uses( 'classes/bBaseDeDados.class.php','base');
$MIOLO->uses( 'classes/bCatalogo.class.php','base');

class bSyncExecute
{
    public static function log($msg)
    {
        function_exists('consoleOutput') ? consoleOutput($msg) : null;
        return $msg . "\r\n";
    }

    public static function executeSync( $syncModule, $mostrarLog = null, bool $materializa = true)
    {
        $log = '';
        $dataInicio = date("Y-m-d H:i:s");
        //Definicao para base de dados funcionar adequadamente utilizando o modulo correto
        if ( !defined('DB_NAME') )
        {
           define('DB_NAME', $syncModule);
        }
        
        //Rodar start.php
        $log .= self::log(_M("Aplicando start.php."));
        bSyncDatabase::runStartScript($syncModule);

        //Sincronizar XMLs
        $log .= self::log(_M("Aplicando alteracoes de arquivos XML."));
        bSyncDatabaseContent::syncAllXML($syncModule, $mostrarLog);

        //Obter arquivos de views e funcoes
        $log .= self::log(_M("Obtendo arquivos de visoes e funcoes da base de dados."));
        $files = self::obterArquivos($syncModule);

        //Dropar views e funcoes
        $log .= self::log(_M("Dropando visoes e funcoes da base de dados."));
        self::droparViewsEFuncoes($files, $syncModule);
        
        //Rodar sync.php
        $log .= self::log(_M("Aplicando sync.php."));
        bSyncDatabase::runSyncScript($syncModule);
        
        //Sincronizar views e funcoes
        $log .= self::log(_M("Recriando/criando visoes e funcoes da base de dados."));
        self::sincronizarViewsEFuncoes($files, $syncModule);

        //Materialização das visões personalizadas
        if ( $materializa )
        {
            $log .= self::log(_M("Rodando tarefa agendada de materialização de visões personalizadas."));
            SAGU::materializarVisoes();
        }
        
        if ( self::verificarSeInstalacaoDevel() )
        {
            $log .= self::log(_M("Verificando dependencias da base de dados."));
            bSyncDatabaseDependencies::verificarDependencias();
        }

        $errors = bSyncDatabaseContent::getErrors($dataInicio);

        if ( !empty($errors) )
        {
            $log .= self::log(_M('Houveram alguns erros no changeDB. Favor verificar.'));
            foreach ($errors as $key => $value) 
            {
                $log .= self::log(_M($value['0']." | ".$value['1']));
            }
        }
        else
        {
            $log .= self::log(_M('SyncDb executado com sucesso.'));
        }
        return $log;
    }

    /**
     * Sincronizar views e funcoes da base de dados.
     * 
     * @param array $files
     */
    public static function sincronizarViewsEFuncoes($files, $syncModule)
    {
        foreach ( $files as $dbSql )
        {
            if ( $dbSql[1] == 'v' )
            {
                $view = new bSyncDatabaseView($dbSql[0], $syncModule);
                $view->syncronize();
            }
            elseif ( $dbSql[1] == 'f' )
            {
                $function = new bSyncDatabaseFunction($dbSql[0], $syncModule);
                $function->syncronize();
            }
        }
        
        return true;
    }
    
    /**
     * Dropa todas as views e as funcoes registradas no arquivo de drop.
     * 
     * @param array $files
     * @param string $syncModule
     * 
     * @return boolean
     */
    public static function droparViewsEFuncoes( $files, $syncModule )
    {
        $MIOLO = MIOLO::getInstance();
        
        //Views: todas sao SEMPRE dropadas
        foreach ( $files as $dbSql )
        {
            if ( $dbSql[1] == 'v' )
            {
                $view = new bSyncDatabaseView($dbSql[0], $syncModule);
                $view->drop();
            }
        }
        
        //Funcoes: sao dropadas SOMENTE as funcoes encontradas no arquivo fDROP.sql
        $dropFile = new bSyncDatabaseFunction($MIOLO->getConf('home.miolo') . '/modules/basic/syncdb/functions/fDROP.txt', $syncModule);
        $dropFile->synchronizeDropFile();
        
        // Precisa recriar as visoes da multi-unidade/multi-centro antes das demais
        bBaseDeDados::executar(file_get_contents($MIOLO->getConf('home.miolo') . '/modules/basic/syncdb/views/v01157-bas_tabelasComMultiUnidade.sql'));
        bBaseDeDados::executar(file_get_contents($MIOLO->getConf('home.miolo') . '/modules/basic/syncdb/views/v01158-bas_tabelasComMultiCentro.sql'));
        bBaseDeDados::executar(file_get_contents($MIOLO->getConf('home.miolo') . '/modules/basic/syncdb/views/v01159-bas_tabelasSemMultiUnidadeOuCentro.sql'));
        bBaseDeDados::executar(file_get_contents($MIOLO->getConf('home.miolo') . '/modules/basic/syncdb/functions/f00108-verificarCentro.sql'));
        bBaseDeDados::executar(file_get_contents($MIOLO->getConf('home.miolo') . '/modules/basic/syncdb/functions/f00106-verificarUnidade.sql'));
        bBaseDeDados::executar(file_get_contents($MIOLO->getConf('home.miolo') . '/modules/basic/syncdb/functions/f00107-obterCentrosPessoaLogada.sql'));
        bBaseDeDados::executar(file_get_contents($MIOLO->getConf('home.miolo') . '/modules/basic/syncdb/functions/f00105-obterUnidadeLogada.sql'));
        
        return true;
    }
    
    /**
     * Obtem arquivos de views e funcoes da base de dados.
     * 
     * @param string $syncModule
     * 
     * @return array
     */
    public static function obterArquivos($syncModule)
    {
        $functions = BSyncDatabaseFunction::listSyncFiles($syncModule);
        $views = bSyncDatabaseView::listSyncFiles($syncModule);
        
        $fv = array_merge($functions, $views);
        
        $final = array();
        foreach ( $fv as $content )
        {
            $pathInfo = pathinfo($content);
            $fileName = substr($pathInfo['filename'], 1);
            $final[$fileName][0] = $content;
            $final[$fileName][1] = substr($pathInfo['filename'], 0, 1);
        }
        
        ksort($final);
        
        return $final;
    }
    
    /**
     * A instalacao e devel quando o arquivo BRANCHE for 'testing'.
     */
    public static function verificarSeInstalacaoDevel()
    {
        $MIOLO = MIOLO::getInstance();
        
        if ( file_exists($MIOLO->getConf('home.miolo') . '/modules/basic/BRANCHE') )
        {
            return (trim(file_get_contents($MIOLO->getConf('home.miolo') . '/modules/basic/BRANCHE')) == 'testing');
        }
        
        return false;
    }
    
    /**
     * Retira caracteres estranhos que o pg_admin coloca nos arquivos
     * 
     * @param string $syncModule
     * 
     * @return array
     */
    public static function strip_tag_pg_admin($content)
    {
        //Retira caracteres estranho que o pg_admin coloca
        $content = str_replace(chr(239), '', $content);
        $content = str_replace(chr(187), '', $content);
        $content = str_replace(chr(191), '', $content);
    
        return $content;
    }
    
}
?>
