<?php
/**
 * File containing the ezcConsoleInput 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 ConsoleTools
 * @version //autogentag//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @filesource
 */

/**
 * The ezcConsoleInput class handles the given options and arguments on the console.
 * 
 * This class allows the complete handling of options and arguments submitted
 * to a console based application.
 *
 * The next example demonstrate how to capture the console options: 
 * 
 * <code>
 * $optionHandler = new ezcConsoleInput();
 * 
 * // Register simple parameter -h/--help
 * $optionHandler->registerOption( new ezcConsoleOption( 'h', 'help' ) );
 * 
 * // Register complex parameter -f/--file
 * $file = new ezcConsoleOption(
 *  'f',
 *  'file',
 *  ezcConsoleInput::TYPE_STRING,
 *  null,
 *  false,
 *  'Process a file.',
 *  'Processes a single file.'
 * );
 * $optionHandler->registerOption( $file );
 * 
 * // Manipulate parameter -f/--file after registration
 * $file->multiple = true;
 * 
 * // Register another complex parameter that depends on -f and excludes -h
 * $dir = new ezcConsoleOption(
 *  'd',
 *  'dir',
 *  ezcConsoleInput::TYPE_STRING,
 *  null,
 *  true,
 *  'Process a directory.',
 *  'Processes a complete directory.',
 *  array( new ezcConsoleOptionRule( $optionHandler->getOption( 'f' ) ) ),
 *  array( new ezcConsoleOptionRule( $optionHandler->getOption( 'h' ) ) )
 * );
 * $optionHandler->registerOption( $dir );
 * 
 * // Register an alias for this parameter
 * $optionHandler->registerAlias( 'e', 'extended-dir', $dir );
 * 
 * // Process registered parameters and handle errors
 * try
 * {
 *      $optionHandler->process( array( 'example_input.php', '-h' ) );
 * }
 * catch ( ezcConsoleOptionException $e )
 * {
 *      echo $e->getMessage();
 *      exit( 1 );
 * }
 * 
 * // Process a single parameter
 * $file = $optionHandler->getOption( 'f' );
 * if ( $file->value === false )
 * {
 *      echo "Parameter -{$file->short}/--{$file->long} was not submitted.\n";
 * }
 * elseif ( $file->value === true )
 * {
 *      echo "Parameter -{$file->short}/--{$file->long} was submitted without value.\n";
 * }
 * else
 * {
 *      echo "Parameter -{$file->short}/--{$file->long} was submitted with value '".var_export($file->value, true)."'.\n";
 * }
 * 
 * // Process all parameters at once:
 * foreach ( $optionHandler->getOptionValues() as $paramShort => $val )
 * {
 *      switch ( true )
 *      {
 *          case $val === false:
 *              echo "Parameter $paramShort was not submitted.\n";
 *              break;
 *          case $val === true:
 *              echo "Parameter $paramShort was submitted without a value.\n";
 *              break;
 *          case is_array( $val ):
 *              echo "Parameter $paramShort was submitted multiple times with value: '".implode(', ', $val)."'.\n";
 *              break;
 *          default:
 *              echo "Parameter $paramShort was submitted with value: '$val'.\n";
 *              break;
 *      }
 * }
 * </code>
 * 
 * @package ConsoleTools
 * @version //autogen//
 * @mainclass
 *
 * @property ezcConsoleArguments $argumentDefinition Optional argument definition.
 */
class ezcConsoleInput
{
    /**
     * Option does not carry a value.
     */
    const TYPE_NONE     = 1;

    /**
     * Option takes an integer value.
     */
    const TYPE_INT      = 2;

    /**
     * Option takes a string value. 
     */
    const TYPE_STRING   = 3;

    /**
     * Array of option definitions, indexed by number.
     *
     * This array stores the ezcConsoleOption objects representing
     * the options.
     *
     * For lookup of an option after its short or long values the attributes
     * {@link ezcConsoleInput::$optionShort}
     * {@link ezcConsoleInput::$optionLong}
     * are used.
     * 
     * @var array(array)
     */
    private $options = array();

    /**
     * Short option names. 
     *
     * Each references a key in {@link ezcConsoleInput::$options}.
     * 
     * @var array(string=>int)
     */
    private $optionShort = array();

    /**
     * Long option names. 
     * 
     * Each references a key in {@link ezcConsoleInput::$options}.
     * 
     * @var array(string=>int)
     */
    private $optionLong = array();

    /**
     * Arguments, if submitted, are stored here. 
     * 
     * @var array(string)
     */
    private $arguments = array();

    /**
     * Wether the process() method has already been called.
     * 
     * @var bool
     */
    private $processed = false;

    /**
     * Indicates if an option was submitted, that has the isHelpOption flag set.
     * 
     * @var bool
     */
    private $helpOptionSet = false;

    /**
     * Tool object for multi-byte encoding safe string operations. 
     * 
     * @var ezcConsoleStringTool
     */
    private $stringTool;

    /**
     * Input validator.
     *
     * @var ezcConsoleInputValidator
     */
    private $validator;

    /**
     * Help generator. 
     * 
     * @var ezcConsoleInputHelpGenerator
     */
    private $helpGenerator;

    /**
     * Collection of properties. 
     * 
     * @var array(string=>mixed)
     */
    protected $properties = array();

    /**
     * Creates an input handler.
     */
    public function __construct()
    {
        $this->argumentDefinition = null;
        $this->stringTool         = new ezcConsoleStringTool();

        // @TODO Verify interface and make plugable
        $this->validator     = new ezcConsoleStandardInputValidator();
        $this->helpGenerator = new ezcConsoleInputStandardHelpGenerator( $this );
    }

    /**
     * Registers the new option $option.
     *
     * This method adds the new option $option to your option collection. If
     * already an option with the assigned short or long value exists, an
     * exception will be thrown.
     *
     * @see ezcConsoleInput::unregisterOption()
     *
     * @param ezcConsoleOption $option
     *
     * @return ezcConsoleOption The recently registered option.
     */
    public function registerOption( ezcConsoleOption $option )
    {
        foreach ( $this->optionShort as $short => $ref )
        {
            if ( $short === $option->short ) 
            {
                throw new ezcConsoleOptionAlreadyRegisteredException( $short );
            }
        }
        foreach ( $this->optionLong as $long => $ref )
        {
            if ( $long === $option->long ) 
            {
                throw new ezcConsoleOptionAlreadyRegisteredException( $long );
            }
        }
        $this->options[] = $option;
        $this->optionLong[$option->long] = $option;
        if ( $option->short !== "" )
        {
            $this->optionShort[$option->short] = $option;
        }
        return $option;
    }

    /**
     * Registers an alias for an option.
     *
     * Registers a new alias for an existing option. Aliases can
     * be used as if they were a normal option.
     *
     * The alias is registered with the short option name $short and the
     * long option name $long. The alias references to the existing 
     * option $option.
     *
     * @see ezcConsoleInput::unregisterAlias()
     *
     * @param string $short
     * @param string $long
     * @param ezcConsoleOption $option
     *
     *
     * @throws ezcConsoleOptionNotExistsException
     *         If the referenced option is not registered.
     * @throws ezcConsoleOptionAlreadyRegisteredException
     *         If another option/alias has taken the provided short or long name.
     * @return void
     */
    public function registerAlias( $short, $long, ezcConsoleOption $option )
    {
        if ( !isset( $this->optionShort[$option->short] ) || !isset( $this->optionLong[$option->long] ) )
        {
            throw new ezcConsoleOptionNotExistsException( $option->long );
        }
        if ( isset( $this->optionShort[$short] ) || isset( $this->optionLong[$long] ) )
        {
            throw new ezcConsoleOptionAlreadyRegisteredException( isset( $this->optionShort[$short] ) ? "-$short" : "--$long" );
        }
        $this->optionShort[$short] = $option;
        $this->optionLong[$long]   = $option;
    }

    /**
     * Registers options according to a string specification.
     *
     * Accepts a string to define parameters and registers all parameters as
     * options accordingly. String definition, specified in $optionDef, looks
     * like this:
     *
     * <code>
     * [s:|size:][u:|user:][a:|all:]
     * </code>
     *
     * This string registers 3 parameters:
     * -s / --size
     * -u / --user
     * -a / --all
     *
     * @param string $optionDef
     * @return void
     * 
     * @throws ezcConsoleOptionStringNotWellformedException 
     *         If provided string does not have the correct format.
     */
    public function registerOptionString( $optionDef ) 
    {
        $regex = '\[([a-z0-9-]+)([:?*+])?([^|]*)\|([a-z0-9-]+)([:?*+])?\]';
        // Check string for wellformedness
        if ( preg_match( "/^($regex)+$/", $optionDef ) == 0 )
        {
            throw new ezcConsoleOptionStringNotWellformedException( "Option definition not wellformed: \"$optionDef\"" );
        }
        if ( preg_match_all( "/$regex/", $optionDef, $matches ) )
        {
            foreach ( $matches[1] as $id => $short )
            {
                $option = null;
                $option = new ezcConsoleOption( $short, $matches[4][$id] );
                if ( !empty( $matches[2][$id] ) || !empty( $matches[5][$id] ) )
                {
                    switch ( !empty( $matches[2][$id] ) ? $matches[2][$id] : $matches[5][$id] )
                    {
                        case '*':
                            // Allows 0 or more occurances
                            $option->multiple = true;
                            break;
                        case '+':
                            // Allows 1 or more occurances
                            $option->multiple = true;
                            $option->type = self::TYPE_STRING;
                            break;
                        case '?':
                            $option->type = self::TYPE_STRING;
                            $option->default = '';
                            break;
                        default:
                            break;
                    }
                }
                if ( !empty( $matches[3][$id] ) )
                {
                    $option->default = $matches[3][$id];
                }
                $this->registerOption( $option );
            }
        }
    }

    /**
     * Removes an option.
     *
     * This function removes an option. All dependencies to that 
     * specific option are removed completely from every other registered 
     * option.
     *
     * @see ezcConsoleInput::registerOption()
     *
     * @param ezcConsoleOption $option The option object to unregister.
     *
     * @throws ezcConsoleOptionNotExistsException
     *         If requesting a not registered option.
     * @return void
     */
    public function unregisterOption( ezcConsoleOption $option )
    {
        $found = false;
        foreach ( $this->options as $id => $existParam )
        {
            if ( $existParam === $option )
            {
                $found = true;
                unset( $this->options[$id] );
                continue;
            }
            $existParam->removeAllExclusions( $option );
            $existParam->removeAllDependencies( $option );
        }
        if ( $found === false )
        {
            throw new ezcConsoleOptionNotExistsException( $option->long );
        }
        foreach ( $this->optionLong as $name => $existParam )
        {
            if ( $existParam === $option )
            {
                unset( $this->optionLong[$name] );
            }
        }
        foreach ( $this->optionShort as $name => $existParam )
        {
            if ( $existParam === $option )
            {
                unset( $this->optionShort[$name] );
            }
        }
    }
    
    /**
     * Removes an alias to an option.
     *
     * This function removes an alias with the short name $short and long
     * name $long.
     *
     * @see ezcConsoleInput::registerAlias()
     * 
     * @throws ezcConsoleOptionNoAliasException
     *      If the requested short/long name belongs to a real parameter instead.
     *
     * @param string $short
     * @param string $long
     * @return void
     *
     * @todo Check if $short and $long refer to the same option!
     */
    public function unregisterAlias( $short, $long )
    {
        foreach ( $this->options as $id => $option )
        {
            if ( $option->short === $short )
            {
                throw new ezcConsoleOptionNoAliasException( $short );
            }
            if ( $option->long === $long )
            {
                throw new ezcConsoleOptionNoAliasException( $long );
            }
        }
        if ( isset( $this->optionShort[$short] ) )
        {
            unset( $this->optionShort[$short] );
        }
        if ( isset( $this->optionLong[$long] ) )
        {
            unset( $this->optionLong[$long] );
        }
    }

    /**
     * Returns the definition object for the option with the name $name.
     *
     * This method receives the long or short name of an option and
     * returns the ezcConsoleOption object.
     * 
     * @param string $name  Short or long name of the option (without - or --).
     * @return ezcConsoleOption
     *
     * @throws ezcConsoleOptionNotExistsException 
     *         If requesting a not registered parameter.
     */
    public function getOption( $name )
    {
        $name = $name;
        if ( isset( $this->optionShort[$name] ) )
        {
            return $this->optionShort[$name];
        }
        if ( isset( $this->optionLong[$name] ) )
        {
            return $this->optionLong[$name];
        }
        throw new ezcConsoleOptionNotExistsException( $name );
    }

    /**
     * Process the input parameters.
     *
     * Actually process the input options and arguments according to the actual 
     * settings.
     * 
     * Per default this method uses $argc and $argv for processing. You can 
     * override this setting with your own input, if necessary, using the
     * parameters of this method. (Attention, first argument is always the pro
     * gram name itself!)
     *
     * All exceptions thrown by this method contain an additional attribute "option"
     * which specifies the parameter on which the error occurred.
     * 
     * @param array(string) $args The arguments
     * @return void
     *
     * @throws ezcConsoleOptionNotExistsException 
     *         If an option that was submitted does not exist.
     * @throws ezcConsoleOptionDependencyViolationException
     *         If a dependency rule was violated. 
     * @throws ezcConsoleOptionExclusionViolationException 
     *         If an exclusion rule was violated.
     * @throws ezcConsoleOptionTypeViolationException 
     *         If the type of a submitted value violates the options type rule.
     * @throws ezcConsoleOptionArgumentsViolationException 
     *         If arguments are passed although a parameter disallowed them.
     *
     * @see ezcConsoleOptionException
     */ 
    public function process( array $args = null )
    {
        if ( $this->processed )
        {
            $this->reset();
        }
        $this->processed = true;

        if ( !isset( $args ) )
        {
            $args = isset( $argv ) ? $argv : isset( $_SERVER['argv'] ) ? $_SERVER['argv'] : array();
        }

        $nextIndex = $this->processOptions( $args );

        if ( $this->helpOptionSet() )
        {
            // No need to parse arguments
            return;
        }

        $this->processArguments( $args, $nextIndex );

        $this->checkRules();

        $this->setOptionDefaults();
    }

    /**
     * Sets defaults for options that have not been submitted.
     *
     * Checks all options if they have been submited. If not and a default 
     * values is present, this is set as the options value.
     */
    private function setOptionDefaults()
    {
        foreach ( $this->options as $option )
        {
            if ( $option->value === false || $option->value === array() )
            {
                // Default value to set?
                if ( $option->default !== null )
                {
                    $option->value = $option->default;
                }
            }
        }
    }

    /**
     * Reads the submitted options from $args array.
     *
     * Returns the next index to check for arguments.
     * 
     * @param array(string) $args 
     * @returns int
     *
     * @throws ezcConsoleOptionNotExistsException
     *         if a submitted option does not exist.
     * @throws ezcConsoleOptionTooManyValuesException
     *         if an option that expects only a single value was submitted 
     *         with multiple values.
     * @throws ezcConsoleOptionTypeViolationException
     *         if an option was submitted with a value of the wrong type.
     * @throws ezcConsoleOptionMissingValueException
     *         if an option thats expects a value was submitted without.
     */
    private function processOptions( array $args )
    {
        $numArgs = count( $args );
        $i = 1;

        while ( $i < $numArgs )
        {
            if ( $args[$i] === '--' )
            {
                break;
            }

            // Equalize parameter handling (long params with =)
            if ( iconv_substr( $args[$i], 0, 2, 'UTF-8' ) == '--' )
            {
                $this->preprocessLongOption( $args, $i );
                // Update number of args, changed by preprocessLongOption()
                $numArgs = count( $args );
            }

            // Check for parameter
            if ( iconv_substr( $args[$i], 0, 1, 'UTF-8' ) === '-' )
            {
                if ( !$this->hasOption( preg_replace( '/^-*/', '', $args[$i] ) ) )
                {
                    throw new ezcConsoleOptionNotExistsException( $args[$i] );
                }
                $this->processOption( $args, $i );
            }
            // Must be the arguments
            else
            {
                break;
            }
        }

        // Move pointer over argument sign
        isset( $args[$i] ) && $args[$i] == '--' ? ++$i : $i;

        return $i;
    }

    /**
     * Resets all option and argument values.
     *
     * This method is called automatically by {@link process()}, if this method
     * is called twice or more, and may also be used to manually reset the
     * values of all registered {@ezcConsoleOption} and {@link
     * ezcConsoleArgument} objects.
     */
    public function reset()
    {
        foreach ( $this->options as $option )
        {
            $option->value = false;
        }
        if ( $this->argumentDefinition !== null )
        {
            foreach ( $this->argumentDefinition as $argument )
            {
                $argument->value = null;
            }
        }
        $this->arguments = array();
    }

    /**
     * Returns true if an option with the given name exists, otherwise false.
     *
     * Checks if an option with the given name is registered.
     * 
     * @param string $name Short or long name of the option.
     * @return bool True if option exists, otherwise false.
     */
    public function hasOption( $name )
    {
        try
        {
            $param = $this->getOption( $name );
        }
        catch ( ezcConsoleOptionNotExistsException $e )
        {
            return false;
        }
        return true;
    }

    /**
     * Returns an array of all registered options.
     *
     * Returns an array of all registered options in the following format:
     * <code>
     * array( 
     *      0 => ezcConsoleOption,
     *      1 => ezcConsoleOption,
     *      2 => ezcConsoleOption,
     *      ...
     * );
     * </code>
     *
     * @return array(string=>ezcConsoleOption) Registered options.
     */
    public function getOptions()
    {
        return $this->options;
    }

    /**
     * Returns the values of all submitted options.
     *
     * Returns an array of all values submitted to the options. The array is 
     * indexed by the parameters short name (excluding the '-' prefix). The array
     * does not contain any parameter, which value is 'false' (meaning: the
     * parameter was not submitted).
     * 
     * @param bool $longnames Wheather to use longnames for indexing.
     * @return array(string=>mixed)
     */
    public function getOptionValues( $longnames = false )
    {
        $res = array();
        foreach ( $this->options as $param )
        {
            if ( $param->value !== false ) 
            {
                $res[( $longnames === true ) ? $param->long : $param->short] = $param->value;
            }
        }
        return $res;
    }

    /**
     * Returns arguments provided to the program.
     *
     * This method returns all arguments provided to a program in an
     * int indexed array. Arguments are sorted in the way
     * they are submitted to the program. You can disable arguments
     * through the 'arguments' flag of a parameter, if you want
     * to disallow arguments.
     *
     * Arguments are either the last part of the program call (if the
     * last parameter is not a 'multiple' one) or divided via the '--'
     * method which is commonly used on Unix (if the last parameter
     * accepts multiple values this is required).
     *
     * @return array(string) Arguments.
     */
    public function getArguments()
    {
        return $this->arguments;
    }

    /**
     * Get help information for your options.
     *
     * This method returns an array of help information for your options,
     * indexed by int. Each help info has 2 fields:
     *
     * 0 => The options names ("<short> / <long>")
     * 1 => The help text (depending on the $long parameter)
     *
     * The $long options determines if you want to get the short or long help
     * texts. The array returned can be used by {@link ezcConsoleTable}.
     *
     * If using the second options, you can filter the options shown in the
     * help output (e.g. to show short help for related options). Provide
     * as simple number indexed array of short and/or long values to set a filter.
     *
     * The $paramGrouping option can be used to group options in the help
     * output. The structure of this array parameter is as follows:
     *
     * <code>
     *  array(
     *      'First section' => array(
     *          'input',
     *          'output'
     *          'overwrite',
     *      ),
     *      'Second section' => array(
     *          'v',
     *          'h',
     *      ),
     *  )
     * </code>
     *
     * As can be seen, short option names are possible as well as long ones.
     * The key of the first array level is the name of the section, which is
     * assigned to an array of options to group under this section. The $params
     * parameter still influences if an option is displayed at all.
     * 
     * @param bool $long
     * @param array(string) $params
     * @param array(string=>array(string)) $paramGrouping
     * @return array(array(string)) Table structure as explained.
     * 
     * @apichange In future versions, the default values of $params will change 
     *            to null instead of an empty array. Giving an empty array for 
     *            these will then be taken literally.
     */
    public function getHelp( $long = false, array $params = array(), array $paramGrouping = null )
    {
        // New handling
        $params = ( $params === array() || $params === null ? null : $params );

        $help = array();
        if ( $paramGrouping === null )
        {
            // Original handling
            $help = $this->getOptionHelpWithoutGrouping( $long, $params );
        }
        else
        {
            $help = $this->getOptionHelpWithGrouping( $long, $params, $paramGrouping );
        }

        if ( $this->argumentDefinition !== null )
        {
            $help[] = array( "Arguments:", '' );

            $argumentsHelp = $this->helpGenerator->generateArgumentHelp( $long );
            if ( $argumentsHelp === array() )
            {
                $help[] = array( '', "No arguments available." );
            }
            else
            {
                $help = array_merge( $help, $argumentsHelp );
            }
        }

        return $help;
    }

    /**
     * Creates the option help array in the original, ungrouped way.
     *
     * Creates the original help array generated by {@link getHelp()}. The
     * $long and $params options are the same as they are for this method.
     * 
     * @param bool $long 
     * @param array $params 
     * @return array
     */
    private function getOptionHelpWithoutGrouping( $long, $params )
    {
        return $this->helpGenerator->generateUngroupedOptionHelp(
            $long,
            $params
        );
    }

    /**
     * Generates options helo array with ordering and grouping.
     * 
     * @param mixed $long 
     * @param mixed $params 
     * @param mixed $paramGrouping 
     * @return array()
     */
    private function getOptionHelpWithGrouping( $long, $params, $paramGrouping )
    {
        $rawHelp = $this->helpGenerator->generateGroupedOptionHelp(
            $paramGrouping,
            $long,
            $params
        );

        $help  = array();
        $first = true;
        foreach ( $rawHelp as $category => $optionsHelp )
        {
            if ( !$first )
            {
                $help[] = array( '', '' );
            }
            else
            {
                $first = false;
            }

            $help[] = array( $category, '' );
            $help = array_merge( $help, $optionsHelp );
        }
        return $help;
    }

    
    /**
     * Get help information for your options as a table.
     *
     * This method provides the information returned by 
     * {@link ezcConsoleInput::getHelp()} in a table.
     *
     * The $paramGrouping option can be used to group options in the help
     * output. The structure of this array parameter is as follows:
     *
     * <code>
     *  array(
     *      'First section' => array(
     *          'input',
     *          'output'
     *          'overwrite',
     *      ),
     *      'Second section' => array(
     *          'v',
     *          'h',
     *      ),
     *  )
     * </code>
     *
     * As can be seen, short option names are possible as well as long ones.
     * The key of the first array level is the name of the section, which is
     * assigned to an array of options to group under this section. The $params
     * parameter still influences if an option as displayed at all.
     * 
     * @param ezcConsoleTable $table     The table object to fill.
     * @param bool $long                 Set this to true for getting the 
     *                                   long help version.
     * @param array(string) $params Set of option names to generate help 
     *                                   for, default is all.
     * @param array(string=>array(string)) $paramGrouping
     * @return ezcConsoleTable           The filled table.
     */
    public function getHelpTable( ezcConsoleTable $table, $long = false, array $params = array(), $paramGrouping = null )
    {
        $help = $this->getHelp( $long, $params, $paramGrouping );
        $i = 0;
        foreach ( $help as $row )
        {
            $table[$i][0]->content = $row[0];
            $table[$i++][1]->content = $row[1];
        }
        return $table;
    }

    /**
     * Returns a standard help output for your program.
     *
     * This method generates a help text as it's commonly known from Unix
     * command line programs. The output will contain the synopsis, your 
     * provided program description and the selected parameter help
     * as also provided by {@link ezcConsoleInput::getHelp()}. The returned
     * string can directly be printed to the console.
     *
     * The $paramGrouping option can be used to group options in the help
     * output. The structure of this array parameter is as follows:
     *
     * <code>
     *  array(
     *      'First section' => array(
     *          'input',
     *          'output'
     *          'overwrite',
     *      ),
     *      'Second section' => array(
     *          'v',
     *          'h',
     *      ),
     *  )
     * </code>
     *
     * As can be seen, short option names are possible as well as long ones.
     * The key of the first array level is the name of the section, which is
     * assigned to an array of options to group under this section. The $params
     * parameter still influences if an option as displayed at all.
     * 
     * @param string $programDesc        The description of your program.
     * @param int $width                 The width to adjust the output text to.
     * @param bool $long                 Set this to true for getting the long 
     *                                   help version.
     * @param array(string) $params Set of option names to generate help 
     *                                   for, default is all.
     * @param array(string=>array(string)) $paramGrouping
     * @return string The generated help text.
     */
    public function getHelpText( $programDesc, $width = 80, $long = false, array $params = null, $paramGrouping = null )
    {
        $help = $this->getHelp( $long, ( $params == null ? array() : $params ), $paramGrouping );

        // Determine max length of first column text.
        $maxLength = 0;
        foreach ( $help as $row )
        {
            $maxLength = max( $maxLength, iconv_strlen( $row[0], 'UTF-8' ) );
        }

        // Width of left column
        $leftColWidth = $maxLength + 2;
        // Width of righ column
        $rightColWidth = $width - $leftColWidth;

        $res = 'Usage: ' . $this->getSynopsis( $params ) . PHP_EOL;
        $res .= $this->stringTool->wordwrap( $programDesc, $width, PHP_EOL );
        $res .= PHP_EOL . PHP_EOL;
        foreach ( $help as $row )
        {
            $rowParts = explode(
                "\n",
                $this->stringTool->wordwrap( $row[1], $rightColWidth )
            );

            $res .= $this->stringTool->strPad( $row[0], $leftColWidth, ' ' );
            $res .= $rowParts[0] . PHP_EOL;
            // @TODO: Fix function call in loop header
            for ( $i = 1; $i < sizeof( $rowParts ); $i++ )
            {
                $res .= str_repeat( ' ', $leftColWidth ) . $rowParts[$i] . PHP_EOL;
            }
        }
        return $res;
    }

    /**
     * Returns the synopsis string for the program.
     *
     * This gives you a synopsis definition for the options and arguments 
     * defined with this instance of ezcConsoleInput. You can filter the 
     * options named in the synopsis by submitting their short names in an
     * array as the parameter of this method. If the parameter $optionNames
     * is set, only those options are listed in the synopsis. 
     * 
     * @param array(string) $optionNames
     * @return string
     */
    public function getSynopsis( array $optionNames = null )
    {
        return $this->helpGenerator->generateSynopsis( $optionNames );
    }

    /**
     * Returns if a help option was set.
     * This method returns if an option was submitted, which was defined to be
     * a help option, using the isHelpOption flag.
     * 
     * @return bool If a help option was set.
     */
    public function helpOptionSet()
    {
        return $this->helpOptionSet;
    }

    /**
     * Property read access.
     *
     * @throws ezcBasePropertyNotFoundException 
     *         If the the desired property is not found.
     * 
     * @param string $propertyName Name of the property.
     * @return mixed Value of the property or null.
     * @ignore
     */
    public function __get( $propertyName )
    {
        if ( !isset( $this->$propertyName ) )
        {
                throw new ezcBasePropertyNotFoundException( $propertyName );
        }
        return $this->properties[$propertyName];
    }

    /**
     * Property set access.
     * 
     * @param string $propertyName 
     * @param string $propertyValue 
     * @ignore
     * @return void
     */
    public function __set( $propertyName, $propertyValue )
    {
        switch ( $propertyName )
        {
            case "argumentDefinition":
                if ( ( $propertyValue instanceof ezcConsoleArguments ) === false && $propertyValue !== null )
                {
                    throw new ezcBaseValueException( $propertyName, $propertyValue, "ezcConsoleArguments" );
                }
                break;
            default:
                throw new ezcBasePropertyNotFoundException( $propertyName );
        }
        $this->properties[$propertyName] = $propertyValue;
    }
    
    /**
     * Property isset access.
     * 
     * @param string $propertyName Name of the property.
     * @return bool True if the property is set, otherwise false.
     * @ignore
     */
    public function __isset( $propertyName )
    {
        return array_key_exists( $propertyName, $this->properties );
    }

    /**
     * Returns the synopsis string for a single option and its dependencies.
     *
     * This method returns a part of the program synopsis, specifically for a
     * certain parameter. The method recursively adds depending parameters up
     * to the 2nd depth level to the synopsis. The second parameter is used
     * to store the short names of all options that have already been used in 
     * the synopsis (to avoid adding an option twice). The 3rd parameter 
     * determines the actual deps in the option dependency recursion to 
     * terminate that after 2 recursions.
     * 
     * @param ezcConsoleOption $option        The option to include.
     * @param array(string) $usedOptions Array of used option short names.
     * @param int $depth                      Current recursion depth.
     * @return string The synopsis for this parameter.
     *
     * @apichange This method is deprecates. Implement your own {@link 
     *            ezcConsoleInputHelpGenerator} instead, as soon as the 
     *            interface is made public.
     */
    protected function createOptionSynopsis( ezcConsoleOption $option, &$usedOptions, $depth = 0 )
    {
        $synopsis = '';

        // Break after a nesting level of 2
        if ( $depth++ > 2 || ( in_array( $option->short, $usedOptions['short'] ) && in_array( $option->long, $usedOptions['long'] ) ) ) return $synopsis;
        
        $usedOptions['short'][] = $option->short;
        $usedOptions['long'][]  = $option->long;
        
        $synopsis .= $option->short !== "" ? "-{$option->short}" : "--{$option->long}";

        if ( isset( $option->default ) )
        {
            $synopsis .= " " . ( $option->type === ezcConsoleInput::TYPE_STRING ? '"' : '' ) . $option->default . ( $option->type === ezcConsoleInput::TYPE_STRING ? '"' : '' );
        }
        else if ( $option->type !== ezcConsoleInput::TYPE_NONE )
        {
            $synopsis .= " ";
            switch ( $option->type )
            {
                case ezcConsoleInput::TYPE_STRING:
                    $synopsis .= "<string>";
                    break;
                case ezcConsoleInput::TYPE_INT:
                    $synopsis .= "<int>";
                    break;
            }
        }

        foreach ( $option->getDependencies() as $rule )
        {
            $deeperSynopsis = $this->createOptionSynopsis( $rule->option, $usedOptions, $depth );
            $synopsis .= ( iconv_strlen( trim( $deeperSynopsis ), 'UTF-8' ) > 0 
                ? ' ' . $deeperSynopsis
                : ''
            );
        }
        
        if ( $option->arguments === false )
        {
            $allowsArgs = false;
        }
        
        // Make the whole thing optional?
        if ( $option->mandatory === false )
        {
            $synopsis = "[$synopsis]";
        }

        return $synopsis . ' ';
    }

    /**
     * Process an option.
     *
     * This method does the processing of a single option. 
     * 
     * @param array(string) $args The arguments array.
     * @param int $i                   The current position in the arguments array.
     * @return void
     *
     * @throws ezcConsoleOptionTooManyValuesException
     *         If an option that expects only a single value was submitted 
     *         with multiple values.
     * @throws ezcConsoleOptionTypeViolationException
     *         If an option was submitted with a value of the wrong type.
     * @throws ezcConsoleOptionMissingValueException
     *         If an option thats expects a value was submitted without.
     */
    private function processOption( array $args, &$i )
    {
        $option = $this->getOption( preg_replace( '/^-+/', '', $args[$i++] ) );

        // Is the actual option a help option?
        if ( $option->isHelpOption === true )
        {
            $this->helpOptionSet = true;
        }
        // No value expected
        if ( $option->type === ezcConsoleInput::TYPE_NONE )
        {
            // No value expected
            if ( isset( $args[$i] ) && iconv_substr( $args[$i], 0, 1, 'UTF-8' ) !== '-' && sizeof( $args ) > ( $i + 1 ) )
            {
                // But one found
                throw new ezcConsoleOptionTypeViolationException( $option, $args[$i] );
            }
            // Multiple occurance possible
            if ( $option->multiple === true )
            {
                $option->value[] = true;
            }
            else
            {
                $option->value = true;
            }
            // Everything fine, nothing to do
            return $i;
        }
        // Value expected, check for it
        if ( isset( $args[$i] ) && iconv_substr( $args[$i], 0, 1, 'UTF-8' ) !== '-' )
        {
            // Type check
            if ( $this->isCorrectType( $option->type, $args[$i] ) === false )
            {
                throw new ezcConsoleOptionTypeViolationException( $option, $args[$i] );
            }
            // Multiple values possible
            if ( $option->multiple === true )
            {
                $option->value[] = $args[$i];
            }
            // Only single value expected, check for multiple
            elseif ( isset( $option->value ) && $option->value !== false )
            {
                throw new ezcConsoleOptionTooManyValuesException( $option );
            }
            else
            {
                $option->value = $args[$i];
            }
            $i++;
        }
        // Value found? If not, use default, if available
        if ( !isset( $option->value ) || $option->value === false || ( is_array( $option->value ) && count( $option->value ) === 0) ) 
        {
            throw new ezcConsoleOptionMissingValueException( $option );
        }
    }

    /**
     * Process arguments given to the program. 
     * 
     * @param array(string) $args The arguments array.
     * @param int $i                   Current index in arguments array.
     * @return void
     */
    private function processArguments( array $args, &$i )
    {
        $numArgs = count( $args );
        if ( $this->argumentDefinition === null || $this->argumentsAllowed() === false )
        {
            // Old argument handling, also used of a set option sets disallowing arguments
            while ( $i < $numArgs )
            {
                $this->arguments[] = $args[$i++];
            }
        }
        else
        {
            $mandatory = true;
            foreach ( $this->argumentDefinition as $arg )
            {
                // Check if all followinga arguments are optional
                if ( $arg->mandatory === false )
                {
                    $mandatory = false;
                }

                // Check if the current argument is present and mandatory
                if ( $mandatory === true )
                {
                    if ( !isset( $args[$i] ) )
                    {
                        throw new ezcConsoleArgumentMandatoryViolationException( $arg );
                    }
                }
                else
                {
                    // Arguments are optional, if no more left: return.
                    if ( !isset( $args[$i] ) )
                    {
                        // Optional and no more arguments left, assign default
                        $arg->value = $arg->default;
                        continue;
                    }
                }

                if ( $arg->multiple === true )
                {
                    $arg->value = array();
                    for ( $i = $i; $i < $numArgs; ++$i )
                    {
                        if ( $this->isCorrectType( $arg->type, $args[$i] ) === false )
                        {
                            throw new ezcConsoleArgumentTypeViolationException( $arg, $args[$i] );
                        }
                        $arg->value = array_merge( $arg->value, array( $args[$i] ) );
                        // Keep old handling, too
                        $this->arguments[] = $args[$i];
                    }
                    return;
                }
                else
                {
                    if ( $this->isCorrectType( $arg->type, $args[$i] ) === false )
                    {
                        throw new ezcConsoleArgumentTypeViolationException( $arg, $args[$i] );
                    }
                    $arg->value = $args[$i];
                    // Keep old handling, too
                    $this->arguments[] = $args[$i];
                }
                ++$i;
            }

            if ( $i < $numArgs )
            {
                throw new ezcConsoleTooManyArgumentsException( $args, $i );
            }
        }
    }

    /**
     * Returns if arguments are allowed with the current option submition.
     * 
     * @return bool If arguments allowed.
     */
    protected function argumentsAllowed()
    {
        foreach ( $this->options as $id => $option )
        {
            if ( $option->value !== false && $option->arguments === false )
            {
                return false;
            }
        }
        return true;
    }

    /**
     * Check the rules that may be associated with an option.
     *
     * Options are allowed to have rules associated for dependencies to other
     * options and exclusion of other options or arguments. This method
     * processes the checks.
     *
     * @throws ezcConsoleException
     *         in case validation fails.
     */
    private function checkRules()
    {
        // If a help option is set, skip rule checking
        if ( $this->helpOptionSet === true )
        {
            return;
        }
        $this->validator->validateOptions(
            $this->options,
            ( $this->arguments !== array() )
        );
    }

    /**
     * Checks if a value is of a given type. Converts the value to the
     * correct PHP type on success.
     *  
     * @param int $type   The type to check for. One of self::TYPE_*.
     * @param string $val The value to check. Will possibly altered!
     * @return bool True on succesful check, otherwise false.
     */
    private function isCorrectType( $type, &$val )
    {
        $res = false;
        switch ( $type )
        {
            case ezcConsoleInput::TYPE_STRING:
                $res = true;
                $val = preg_replace( '/^(["\'])(.*)\1$/', '\2', $val );
                break;
            case ezcConsoleInput::TYPE_INT:
                $res = preg_match( '/^[0-9]+$/', $val ) ? true : false;
                if ( $res )
                {
                    $val = ( int ) $val;
                }
                break;
        }
        return $res;
    }

    /**
     * Split parameter and value for long option names. 
     * 
     * This method checks for long options, if the value is passed using =. If
     * this is the case parameter and value get split and replaced in the
     * arguments array.
     * 
     * @param array(string) $args The arguments array
     * @param int $i                   Current arguments array position
     * @return void
     */
    private function preprocessLongOption( array &$args, $i )
    {
        // Value given?
        if ( preg_match( '/^--\w+\=[^ ]/i', $args[$i] ) )
        {
            // Split param and value and replace current param
            $parts = explode( '=', $args[$i], 2 );
            array_splice( $args, $i, 1, $parts );
        }
    }
}
?>
