/**
 * 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 org.apache.commons.cli;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

/**
 * The class PosixParser provides an implementation of the 
 * {@link Parser#flatten(Options,String[],boolean) flatten} method.
 *
 * @author John Keyes (john at integralsource.com)
 * @see Parser
 * @version $Revision$
 */
public class PosixParser extends Parser {

    /** holder for flattened tokens */
    private ArrayList tokens = new ArrayList();

    /** specifies if bursting should continue */
    private boolean eatTheRest;

    /** holder for the current option */
    private Option currentOption;

    /** the command line Options */
    private Options options;

    /**
     * <p>Resets the members to their original state i.e. remove
     * all of <code>tokens</code> entries, set <code>eatTheRest</code>
     * to false and set <code>currentOption</code> to null.</p>
     */
    private void init()
    {
        eatTheRest = false;
        tokens.clear();
        currentOption = null;
    }

    /**
     * <p>An implementation of {@link Parser}'s abstract
     * {@link Parser#flatten(Options,String[],boolean) flatten} method.</p>
     *
     * <p>The following are the rules used by this flatten method.
     * <ol>
     *  <li>if <code>stopAtNonOption</code> is <b>true</b> then do not
     *  burst anymore of <code>arguments</code> entries, just add each
     *  successive entry without further processing.  Otherwise, ignore
     *  <code>stopAtNonOption</code>.</li>
     *  <li>if the current <code>arguments</code> entry is "<b>--</b>"
     *  just add the entry to the list of processed tokens</li>
     *  <li>if the current <code>arguments</code> entry is "<b>-</b>"
     *  just add the entry to the list of processed tokens</li>
     *  <li>if the current <code>arguments</code> entry is two characters
     *  in length and the first character is "<b>-</b>" then check if this
     *  is a valid {@link Option} id.  If it is a valid id, then add the
     *  entry to the list of processed tokens and set the current {@link Option}
     *  member.  If it is not a valid id and <code>stopAtNonOption</code>
     *  is true, then the remaining entries are copied to the list of 
     *  processed tokens.  Otherwise, the current entry is ignored.</li>
     *  <li>if the current <code>arguments</code> entry is more than two
     *  characters in length and the first character is "<b>-</b>" then
     *  we need to burst the entry to determine its constituents.  For more
     *  information on the bursting algorithm see 
     *  {@link PosixParser#burstToken(String, boolean) burstToken}.</li>
     *  <li>if the current <code>arguments</code> entry is not handled 
     *  by any of the previous rules, then the entry is added to the list
     *  of processed tokens.</li>
     * </ol>
     * </p>
     *
     * @param options The command line {@link Options}
     * @param arguments The command line arguments to be parsed
     * @param stopAtNonOption Specifies whether to stop flattening
     * when an non option is found.
     * @return The flattened <code>arguments</code> String array.
     */
    protected String[] flatten(Options options, String[] arguments, 
                               boolean stopAtNonOption)
    {
        init();
        this.options = options;

        // an iterator for the command line tokens
        Iterator iter = Arrays.asList(arguments).iterator();
        String token;

        // process each command line token
        while (iter.hasNext())
        {
            // get the next command line token
            token = (String) iter.next();

            // handle SPECIAL TOKEN
            if (token.startsWith("--"))
            {
                if (token.indexOf('=') != -1)
                {
                    tokens.add(token.substring(0, token.indexOf('=')));
                    tokens.add(token.substring(token.indexOf('=') + 1, 
                                               token.length()));
                }
                else
                {
                    tokens.add(token);
                }
            }

            // single hyphen
            else if ("-".equals(token))
            {
                processSingleHyphen(token);
            }
            else if (token.startsWith("-"))
            {
                int tokenLength = token.length();

                if (tokenLength == 2)
                {
                    processOptionToken(token, stopAtNonOption);
                }
                else if (options.hasOption(token)) {
                	tokens.add(token);
                }
                // requires bursting
                else
                {
                    burstToken(token, stopAtNonOption);
                }
            }
            else
            {
                if (stopAtNonOption)
                {
                    process(token);
                }
                else
                {
                    tokens.add(token);
                }
            }

            gobble(iter);
        }

        return (String[]) tokens.toArray(new String[tokens.size()]);
    }

    /**
     * <p>Adds the remaining tokens to the processed tokens list.</p>
     *
     * @param iter An iterator over the remaining tokens
     */
    private void gobble(Iterator iter)
    {
        if (eatTheRest)
        {
            while (iter.hasNext())
            {
                tokens.add(iter.next());
            }
        }
    }

    /**
     * <p>If there is a current option and it can have an argument
     * value then add the token to the processed tokens list and 
     * set the current option to null.</p>
     * <p>If there is a current option and it can have argument
     * values then add the token to the processed tokens list.</p>
     * <p>If there is not a current option add the special token
     * "<b>--</b>" and the current <code>value</code> to the processed
     * tokens list.  The add all the remaining <code>argument</code>
     * values to the processed tokens list.</p>
     *
     * @param value The current token
     */
    private void process(String value)
    {
        if ((currentOption != null) && currentOption.hasArg())
        {
            if (currentOption.hasArg())
            {
                tokens.add(value);
                currentOption = null;
            }
            else if (currentOption.hasArgs())
            {
                tokens.add(value);
            }
        }
        else
        {
            eatTheRest = true;
            tokens.add("--");
            tokens.add(value);
        }
    }

    /**
     * <p>If it is a hyphen then add the hyphen directly to
     * the processed tokens list.</p>
     *
     * @param hyphen The hyphen token
     */
    private void processSingleHyphen(String hyphen)
    {
        tokens.add(hyphen);
    }

    /**
     * <p>If an {@link Option} exists for <code>token</code> then
     * set the current option and add the token to the processed 
     * list.</p>
     * <p>If an {@link Option} does not exist and <code>stopAtNonOption</code>
     * is set then ignore the current token and add the remaining tokens
     * to the processed tokens list directly.</p>
     *
     * @param token The current option token
     * @param stopAtNonOption Specifies whether flattening should halt
     * at the first non option.
     */
    private void processOptionToken(String token, boolean stopAtNonOption)
    {
        if (this.options.hasOption(token))
        {
            currentOption = this.options.getOption(token);
            tokens.add(token);
        }
        else if (stopAtNonOption)
        {
            eatTheRest = true;
        }
    }

    /**
     * <p>Breaks <code>token</code> into its constituent parts
     * using the following algorithm.
     * <ul>
     *  <li>ignore the first character ("<b>-</b>")</li>
     *  <li>foreach remaining character check if an {@link Option}
     *  exists with that id.</li>
     *  <li>if an {@link Option} does exist then add that character
     *  prepended with "<b>-</b>" to the list of processed tokens.</li>
     *  <li>if the {@link Option} can have an argument value and there 
     *  are remaining characters in the token then add the remaining 
     *  characters as a token to the list of processed tokens.</li>
     *  <li>if an {@link Option} does <b>NOT</b> exist <b>AND</b> 
     *  <code>stopAtNonOption</code> <b>IS</b> set then add the special token
     *  "<b>--</b>" followed by the remaining characters and also 
     *  the remaining tokens directly to the processed tokens list.</li>
     *  <li>if an {@link Option} does <b>NOT</b> exist <b>AND</b>
     *  <code>stopAtNonOption</code> <b>IS NOT</b> set then add that
     *  character prepended with "<b>-</b>".</li>
     * </ul>
     * </p>
     *
     * @param token The current token to be <b>burst</b>
     * @param stopAtNonOption Specifies whether to stop processing
     * at the first non-Option encountered.
     */
    protected void burstToken(String token, boolean stopAtNonOption)
    {
        int tokenLength = token.length();

        for (int i = 1; i < tokenLength; i++)
        {
            String ch = String.valueOf(token.charAt(i));
            boolean hasOption = options.hasOption(ch);

            if (hasOption)
            {
                tokens.add("-" + ch);
                currentOption = options.getOption(ch);

                if (currentOption.hasArg() && (token.length() != (i + 1)))
                {
                    tokens.add(token.substring(i + 1));

                    break;
                }
            }
            else if (stopAtNonOption)
            {
                process(token.substring(i));
            }
            else
            {
                tokens.add(token);
                break;
            }
        }
    }
}
