<?php
/**
 * File containing the ezcBase class.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @package Base
 * @version //autogentag//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */
/**
 * Base class implements the methods needed to use the eZ components.
 *
 * @package Base
 * @version //autogentag//
 * @mainclass
 */
class ezcBase
{
    /**
     * Used for dependency checking, to check for a PHP extension.
     */
    const DEP_PHP_EXTENSION = "extension";

    /**
     * Used for dependency checking, to check for a PHP version.
     */
    const DEP_PHP_VERSION = "version";

    /**
     * Denotes the production mode
     */
    const MODE_PRODUCTION = 0;

    /**
     * Denotes the development mode
     */
    const MODE_DEVELOPMENT = 1;

    /**
     * Indirectly it determines the path where the autoloads are stored.
     *
     * @var string
     */
    private static $libraryMode = "devel";

    /**
     * Contains the current working directory, which is used when the
     * $libraryMode is set to "custom".
     *
     * @var string
     */
    private static $currentWorkingDirectory = null;

    /**
     * The full path to the autoload directory.
     *
     * @var string
     */
    protected static $packageDir = null;

    /**
     * Contains which development mode is used. It's "development" by default,
     * because of backwards compatibility reasons.
     */
    private static $runMode = self::MODE_DEVELOPMENT;

    /**
     * Stores info with additional paths where autoload files and classes for
     * autoloading could be found. Each item of $repositoryDirs looks like
     * array( autoloadFileDir, baseDir ). The array key is the prefix belonging
     * to classes within that repository - if provided when calling
     * addClassRepository(), or an autoincrement integer otherwise.
     *
     * @var array(string=>array)
     */
    protected static $repositoryDirs = array();

    /**
     * This variable stores all the elements from the autoload arrays. When a
     * new autoload file is loaded, their files are added to this array.
     *
     * @var array(string=>string)
     */
    protected static $autoloadArray = array();

    /**
     * This variable stores all the elements from the autoload arrays for
     * external repositories. When a new autoload file is loaded, their files
     * are added to this array.
     *
     * @var array(string=>string)
     */
    protected static $externalAutoloadArray = array();

    /**
     * Options for the ezcBase class.
     *
     * @var ezcBaseOptions
     */
    static private $options;

    /**
     * Associates an option object with this static class.
     *
     * @param ezcBaseAutoloadOptions $options
     */
    static public function setOptions( ezcBaseAutoloadOptions $options )
    {
        self::$options = $options;
    }

    /**
     * Tries to autoload the given className. If the className could be found
     * this method returns true, otherwise false.
     *
     * This class caches the requested class names (including the ones who
     * failed to load).
     *
     * @param string $className  The name of the class that should be loaded.
     *
     * @return bool
     */
    public static function autoload( $className )
    {
        ezcBase::setPackageDir();

        // Check whether the classname is already in the cached autoloadArray.
        if ( array_key_exists( $className, ezcBase::$autoloadArray ) )
        {
            // Is it registered as 'unloadable'?
            if ( ezcBase::$autoloadArray[$className] == false )
            {
                return false;
            }
            ezcBase::loadFile( ezcBase::$autoloadArray[$className] );

            return true;
        }

        // Check whether the classname is already in the cached autoloadArray
        // for external repositories.
        if ( array_key_exists( $className, ezcBase::$externalAutoloadArray ) )
        {
            // Is it registered as 'unloadable'?
            if ( ezcBase::$externalAutoloadArray[$className] == false )
            {
                return false;
            }
            ezcBase::loadExternalFile( ezcBase::$externalAutoloadArray[$className] );

            return true;
        }

        // Not cached, so load the autoload from the package.
        // Matches the first and optionally the second 'word' from the classname.
        $fileNames = array();
        if ( preg_match( "/^([a-z0-9]*)([A-Z][a-z0-9]*)?([A-Z][a-z0-9]*)?/", $className, $matches ) !== false )
        {
            $autoloadFile = "";
            // Try to match with both names, if available.
            switch ( sizeof( $matches ) )
            {
                case 4:
                    // check for x_y_autoload.php
                    $autoloadFile = strtolower( "{$matches[2]}_{$matches[3]}_autoload.php" );
                    $fileNames[] = $autoloadFile;
                    if ( ezcBase::requireFile( $autoloadFile, $className, $matches[1] ) )
                    {
                        return true;
                    }
                    // break intentionally missing.

                case 3:
                    // check for x_autoload.php
                    $autoloadFile = strtolower( "{$matches[2]}_autoload.php" );
                    $fileNames[] = $autoloadFile;
                    if ( ezcBase::requireFile( $autoloadFile, $className, $matches[1] ) )
                    {
                        return true;
                    }
                    // break intentionally missing.

                case 2:
                    // check for autoload.php
                    $autoloadFile = 'autoload.php';
                    $fileNames[] = $autoloadFile;
                    if ( ezcBase::requireFile( $autoloadFile, $className, $matches[1] ) )
                    {
                        return true;
                    }
                    break;
            }

            // Maybe there is another autoload available.
            // Register this classname as false.
            ezcBase::$autoloadArray[$className] = false;
        }

        $path = ezcBase::$packageDir . 'autoload/';
        $realPath = realpath( $path );

        if ( $realPath == '' )
        {
            // Can not be tested, because if this happens, then the autoload
            // environment has not been set-up correctly.
            trigger_error( "Couldn't find autoload directory '$path'", E_USER_ERROR );
        }

        $dirs = self::getRepositoryDirectories();
        if ( ezcBase::$options && ezcBase::$options->debug )
        {
            throw new ezcBaseAutoloadException( $className, $fileNames, $dirs );
        }

        return false;
    }

    /**
     * Sets the current working directory to $directory.
     *
     * @param string $directory
     */
    public static function setWorkingDirectory( $directory )
    {
        self::$libraryMode = 'custom';
        self::$currentWorkingDirectory = $directory;
    }

    /**
     * Figures out the base path of the Zeta Components installation.
     *
     * It stores the path that it finds in a static member variable. The path
     * depends on the installation method of the Zeta Components. The SVN version
     * has a different path than the PEAR installed version.
     */
    protected static function setPackageDir()
    {
        if ( ezcBase::$packageDir !== null )
        {
            return;
        }

        // Get the path to the components.
        $baseDir = dirname( __FILE__ );

        switch ( ezcBase::$libraryMode )
        {
            case "custom":
                ezcBase::$packageDir = self::$currentWorkingDirectory . '/';
                break;
            case "devel":
            case "tarball":
                ezcBase::$packageDir = $baseDir. "/../../";
                break;
            case "pear";
                ezcBase::$packageDir = $baseDir. "/../";
                break;
        }
    }

    /**
     * Tries to load the autoload array and, if loaded correctly, includes the class.
     *
     * @param string $fileName    Name of the autoload file.
     * @param string $className   Name of the class that should be autoloaded.
     * @param string $prefix      The prefix of the class repository.
     *
     * @return bool  True is returned when the file is correctly loaded.
     *                   Otherwise false is returned.
     */
    protected static function requireFile( $fileName, $className, $prefix )
    {
        $autoloadDir = ezcBase::$packageDir . "autoload/";

        // We need the full path to the fileName. The method file_exists() doesn't
        // automatically check the (php.ini) library paths. Therefore:
        // file_exists( "ezc/autoload/$fileName" ) doesn't work.
        if ( $prefix === 'ezc' && file_exists( "$autoloadDir$fileName" ) )
        {
            $array = require( "$autoloadDir$fileName" );

            if ( is_array( $array) && array_key_exists( $className, $array ) )
            {
                // Add the array to the cache, and include the requested file.
                ezcBase::$autoloadArray = array_merge( ezcBase::$autoloadArray, $array );
                if ( ezcBase::$options !== null && ezcBase::$options->preload && !preg_match( '/Exception$/', $className ) )
                {
                    foreach ( $array as $loadClassName => $file )
                    {
                        if ( $loadClassName !== 'ezcBase' && !class_exists( $loadClassName, false ) && !interface_exists( $loadClassName, false ) && !preg_match( '/Exception$/', $loadClassName ) /*&& !class_exists( $loadClassName, false ) && !interface_exists( $loadClassName, false )*/ )
                        {
                            ezcBase::loadFile( ezcBase::$autoloadArray[$loadClassName] );
                        }
                    }
                }
                else
                {
                    ezcBase::loadFile( ezcBase::$autoloadArray[$className] );
                }
                return true;
            }
        }

        // It is not in components autoload/ dir.
        // try to search in additional dirs.
        foreach ( ezcBase::$repositoryDirs as $repositoryPrefix => $extraDir )
        {
            if ( gettype( $repositoryPrefix ) === 'string' && $repositoryPrefix !== $prefix )
            {
                continue;
            }

            if ( file_exists( $extraDir['autoloadDirPath'] . '/' . $fileName ) )
            {
                $array = array();
                $originalArray = require( $extraDir['autoloadDirPath'] . '/' . $fileName );

                // Building paths.
                // Resulting path to class definition file consists of:
                // path to extra directory with autoload file +
                // basePath provided for current extra directory +
                // path to class definition file stored in autoload file.
                foreach ( $originalArray as $class => $classPath )
                {
                    $array[$class] = $extraDir['basePath'] . '/' . $classPath;
                }

                if ( is_array( $array ) && array_key_exists( $className, $array ) )
                {
                    // Add the array to the cache, and include the requested file.
                    ezcBase::$externalAutoloadArray = array_merge( ezcBase::$externalAutoloadArray, $array );
                    ezcBase::loadExternalFile( ezcBase::$externalAutoloadArray[$className] );
                    return true;
                }
            }
        }

        // Nothing found :-(.
        return false;
    }

    /**
     * Loads, require(), the given file name. If we are in development mode,
     * "/src/" is inserted into the path.
     *
     * @param string $file  The name of the file that should be loaded.
     */
    protected static function loadFile( $file )
    {
        switch ( ezcBase::$libraryMode )
        {
            case "devel":
            case "tarball":
                list( $first, $second ) = explode( '/', $file, 2 );
                $file = $first . "/src/" . $second;
                break;

            case "custom":
                list( $first, $second ) = explode( '/', $file, 2 );
                // Add the "src/" after the package name.
                if ( $first == 'Base' || $first == 'UnitTest' )
                {
                    list( $first, $second ) = explode( '/', $file, 2 );
                    $file = $first . "/src/" . $second;
                }
                else
                {
                    list( $first, $second, $third ) = explode( '/', $file, 3 );
                    $file = $first . '/' . $second . "/src/" . $third;
                }
                break;

            case "pear":
                /* do nothing, it's already correct */
                break;
        }

        if ( file_exists( ezcBase::$packageDir . $file ) )
        {
            require( ezcBase::$packageDir . $file );
        }
        else
        {
            // Can not be tested, because if this happens, then one of the
            // components has a broken autoload file.
            throw new ezcBaseFileNotFoundException( ezcBase::$packageDir.$file );
        }
    }

    /**
     * Loads, require(), the given file name from an external package.
     *
     * @param string $file  The name of the file that should be loaded.
     */
    protected static function loadExternalFile( $file )
    {
        if ( file_exists( $file ) )
        {
            require( $file );
        }
        else
        {
            throw new ezcBaseFileNotFoundException( $file );
        }
    }

    /**
     * Checks for dependencies on PHP versions or extensions
     *
     * The function as called by the $component component checks for the $type
     * dependency. The dependency $type is compared against the $value. The
     * function aborts the script if the dependency is not matched.
     *
     * @param string $component
     * @param int $type
     * @param mixed $value
     */
    public static function checkDependency( $component, $type, $value )
    {
        switch ( $type )
        {
            case self::DEP_PHP_EXTENSION:
                if ( extension_loaded( $value ) )
                {
                    return;
                }
                else
                {
                    // Can not be tested as it would abort the PHP script.
                    die( "\nThe {$component} component depends on the default PHP extension '{$value}', which is not loaded.\n" );
                }
                break;

            case self::DEP_PHP_VERSION:
                $phpVersion = phpversion();
                if ( version_compare( $phpVersion, $value, '>=' ) )
                {
                    return;
                }
                else
                {
                    // Can not be tested as it would abort the PHP script.
                    die( "\nThe {$component} component depends on the PHP version '{$value}', but the current version is '{$phpVersion}'.\n" );
                }
                break;
        }
    }

    /**
     * Return the list of directories that contain class repositories.
     *
     * The path to the eZ components directory is always included in the result
     * array. Each element in the returned array has the format of:
     * packageDirectory => ezcBaseRepositoryDirectory
     *
     * @return array(string=>ezcBaseRepositoryDirectory)
     */
    public static function getRepositoryDirectories()
    {
        $autoloadDirs = array();
        ezcBase::setPackageDir();
        $repositoryDir = self::$currentWorkingDirectory ? self::$currentWorkingDirectory : ( realpath( dirname( __FILE__ ) . '/../../' ) );
        $autoloadDirs['ezc'] = new ezcBaseRepositoryDirectory( ezcBaseRepositoryDirectory::TYPE_INTERNAL, $repositoryDir, $repositoryDir . "/autoload" );

        foreach ( ezcBase::$repositoryDirs as $extraDirKey => $extraDirArray )
        {
            $repositoryDirectory = new ezcBaseRepositoryDirectory( ezcBaseRepositoryDirectory::TYPE_EXTERNAL, realpath( $extraDirArray['basePath'] ), realpath( $extraDirArray['autoloadDirPath'] ) );
            $autoloadDirs[$extraDirKey] = $repositoryDirectory;
        }

        return $autoloadDirs;
    }

    /**
     * Adds an additional class repository.
     *
     * Used for adding class repositoryies outside the eZ components to be
     * loaded by the autoload system.
     *
     * This function takes two arguments: $basePath is the base path for the
     * whole class repository and $autoloadDirPath the path where autoload
     * files for this repository are found. The paths in the autoload files are
     * relative to the package directory as specified by the $basePath
     * argument. I.e. class definition file will be searched at location
     * $basePath + path to the class definition file as stored in the autoload
     * file.
     *
     * addClassRepository() should be called somewhere in code before external classes
     * are used.
     *
     * Example:
     * Take the following facts:
     * <ul>
     * <li>there is a class repository stored in the directory "./repos"</li>
     * <li>autoload files for that repository are stored in "./repos/autoloads"</li>
     * <li>there are two components in this repository: "Me" and "You"</li>
     * <li>the "Me" component has the classes "erMyClass1" and "erMyClass2"</li>
     * <li>the "You" component has the classes "erYourClass1" and "erYourClass2"</li>
     * </ul>
     *
     * In this case you would need to create the following files in
     * "./repos/autoloads". Please note that the part before _autoload.php in
     * the filename is the first part of the <b>classname</b>, not considering
     * the all lower-case letter prefix.
     *
     * "my_autoload.php":
     * <code>
     * <?php
     *     return array (
     *       'erMyClass1' => 'Me/myclass1.php',
     *       'erMyClass2' => 'Me/myclass2.php',
     *     );
     * ?>
     * </code>
     *
     * "your_autoload.php":
     * <code>
     * <?php
     *     return array (
     *       'erYourClass1' => 'You/yourclass1.php',
     *       'erYourClass2' => 'You/yourclass2.php',
     *     );
     * ?>
     * </code>
     *
     * The directory structure for the external repository is then:
     * <code>
     * ./repos/autoloads/my_autoload.php
     * ./repos/autoloads/you_autoload.php
     * ./repos/Me/myclass1.php
     * ./repos/Me/myclass2.php
     * ./repos/You/yourclass1.php
     * ./repos/You/yourclass2.php
     * </code>
     *
     * To use this repository with the autoload mechanism you have to use the
     * following code:
     * <code>
     * <?php
     * ezcBase::addClassRepository( './repos', './repos/autoloads' );
     * $myVar = new erMyClass2();
     * ?>
     * </code>
     *
     * @throws ezcBaseFileNotFoundException if $autoloadDirPath or $basePath do not exist.
     * @param string $basePath
     * @param string $autoloadDirPath
     * @param string $prefix
     */
    public static function addClassRepository( $basePath, $autoloadDirPath = null, $prefix = null )
    {
        // check if base path exists
        if ( !is_dir( $basePath ) )
        {
            throw new ezcBaseFileNotFoundException( $basePath, 'base directory' );
        }

        // calculate autoload path if it wasn't given
        if ( is_null( $autoloadDirPath ) )
        {
            $autoloadDirPath = $basePath . '/autoload';
        }

        // check if autoload dir exists
        if ( !is_dir( $autoloadDirPath ) )
        {
            throw new ezcBaseFileNotFoundException( $autoloadDirPath, 'autoload directory' );
        }

        // add info to $repositoryDirs
        if ( $prefix === null )
        {
            $array = array( 'basePath' => $basePath, 'autoloadDirPath' => $autoloadDirPath );

            // add info to the list of extra dirs
            ezcBase::$repositoryDirs[] = $array;
        }
        else
        {
            if ( array_key_exists( $prefix, ezcBase::$repositoryDirs ) )
            {
                throw new ezcBaseDoubleClassRepositoryPrefixException( $prefix, $basePath, $autoloadDirPath );
            }

            // add info to the list of extra dirs, and use the prefix to identify the new repository.
            ezcBase::$repositoryDirs[$prefix] = array( 'basePath' => $basePath, 'autoloadDirPath' => $autoloadDirPath );
        }
    }

    /**
     * Returns the base path of the Zeta Components installation
     *
     * This method returns the base path, including a trailing directory
     * separator.
     *
     * @return string
     */
    public static function getInstallationPath()
    {
        self::setPackageDir();

        $path = realpath( self::$packageDir );
        if ( substr( $path, -1 ) !== DIRECTORY_SEPARATOR )
        {
            $path .= DIRECTORY_SEPARATOR;
        }
        return $path;
    }

    /**
     * Sets the development mode to the one specified.
     *
     * @param int $runMode
     */
    public static function setRunMode( $runMode )
    {
        if ( !in_array( $runMode, array( ezcBase::MODE_PRODUCTION, ezcBase::MODE_DEVELOPMENT ) ) )
        {
            throw new ezcBaseValueException( 'runMode', $runMode, 'ezcBase::MODE_PRODUCTION or ezcBase::MODE_DEVELOPMENT' );
        }

        self::$runMode = $runMode;
    }

    /**
     * Returns the current development mode.
     *
     * @return int
     */
    public static function getRunMode()
    {
        return self::$runMode;
    }

    /**
     * Returns true when we are in development mode.
     *
     * @return bool
     */
    public static function inDevMode()
    {
        return self::$runMode == ezcBase::MODE_DEVELOPMENT;
    }

    /**
     * Returns the installation method
     *
     * Possible return values are 'custom', 'devel', 'tarball' and 'pear'. Only
     * 'tarball' and 'pear' are returned for user-installed versions.
     *
     * @return string
     */
    public static function getInstallMethod()
    {
        return self::$libraryMode;
    }
}
?>