/*
 * 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.felix.utils.manifest;

import java.util.ArrayList;
import java.util.List;

public final class Parser
{
    private Parser() { }

    public static Clause[] parseHeader(String header) throws IllegalArgumentException
    {
        Clause[] clauses = null;
        if (header != null)
        {
            if (header.length() == 0)
            {
                throw new IllegalArgumentException("The header cannot be an empty string.");
            }
            String[] ss = parseDelimitedString(header, ",");
            clauses = parseClauses(ss);
        }
        return (clauses == null) ? new Clause[0] : clauses;
    }

    public static Clause[] parseClauses(String[] ss) throws IllegalArgumentException
    {
        if (ss == null)
        {
            return null;
        }

        List completeList = new ArrayList();
        for (int ssIdx = 0; ssIdx < ss.length; ssIdx++)
        {
            // Break string into semi-colon delimited pieces.
            String[] pieces = parseDelimitedString(ss[ssIdx], ";");

            // Count the number of different clauses; clauses
            // will not have an '=' in their string. This assumes
            // that clauses come first, before directives and
            // attributes.
            int pathCount = 0;
            for (int pieceIdx = 0; pieceIdx < pieces.length; pieceIdx++)
            {
                if (pieces[pieceIdx].indexOf('=') >= 0)
                {
                    break;
                }
                pathCount++;
            }

            // Error if no packages were specified.
            if (pathCount == 0)
            {
                throw new IllegalArgumentException("No path specified on clause: " + ss[ssIdx]);
            }

            // Parse the directives/attributes.
            Directive[] dirs = new Directive[pieces.length - pathCount];
            Attribute[] attrs = new Attribute[pieces.length - pathCount];
            int dirCount = 0, attrCount = 0;
            int idx = -1;
            String sep = null;
            for (int pieceIdx = pathCount; pieceIdx < pieces.length; pieceIdx++)
            {
                if ((idx = pieces[pieceIdx].indexOf("=")) <= 0)
                {
                    // It is an error.
                    throw new IllegalArgumentException("Not a directive/attribute: " + ss[ssIdx]);
                }
                // This a directive.
                if (pieces[pieceIdx].charAt(idx - 1) == ':')
                {
                    idx--;
                    sep = ":=";
                }
                // This an attribute.
                else
                {
                    sep = "=";
                }

                String key = pieces[pieceIdx].substring(0, idx).trim();
                String value = pieces[pieceIdx].substring(idx + sep.length()).trim();

                // Remove quotes, if value is quoted.
                if (value.startsWith("\"") && value.endsWith("\""))
                {
                    value = value.substring(1, value.length() - 1);
                }

                // Save the directive/attribute in the appropriate array.
                if (sep.equals(":="))
                {
                    dirs[dirCount++] = new Directive(key, value);
                }
                else
                {
                    attrs[attrCount++] = new Attribute(key, value);
                }
            }

            // Shrink directive array.
            Directive[] dirsFinal = new Directive[dirCount];
            System.arraycopy(dirs, 0, dirsFinal, 0, dirCount);
            // Shrink attribute array.
            Attribute[] attrsFinal = new Attribute[attrCount];
            System.arraycopy(attrs, 0, attrsFinal, 0, attrCount);

            // Create package attributes for each package and
            // set directives/attributes. Add each package to
            // completel list of packages.
            Clause[] pkgs = new Clause[pathCount];
            for (int pkgIdx = 0; pkgIdx < pathCount; pkgIdx++)
            {
                pkgs[pkgIdx] = new Clause(pieces[pkgIdx], dirsFinal, attrsFinal);
                completeList.add(pkgs[pkgIdx]);
            }
        }

        Clause[] pkgs = (Clause[]) completeList.toArray(new Clause[completeList.size()]);
        return pkgs;
    }

    /**
     * Parses delimited string and returns an array containing the tokens. This
     * parser obeys quotes, so the delimiter character will be ignored if it is
     * inside of a quote. This method assumes that the quote character is not
     * included in the set of delimiter characters.
     * @param value the delimited string to parse.
     * @param delim the characters delimiting the tokens.
     * @return an array of string tokens or null if there were no tokens.
    **/
    public static String[] parseDelimitedString(String value, String delim)
    {
        if (value == null)
        {
           value = "";
        }

        List list = new ArrayList();

        int CHAR = 1;
        int DELIMITER = 2;
        int STARTQUOTE = 4;
        int ENDQUOTE = 8;

        StringBuffer sb = new StringBuffer();

        int expecting = (CHAR | DELIMITER | STARTQUOTE);

        for (int i = 0; i < value.length(); i++)
        {
            char c = value.charAt(i);

            boolean isDelimiter = (delim.indexOf(c) >= 0);
            boolean isQuote = (c == '"');

            if (isDelimiter && ((expecting & DELIMITER) > 0))
            {
                list.add(sb.toString().trim());
                sb.delete(0, sb.length());
                expecting = (CHAR | DELIMITER | STARTQUOTE);
            }
            else if (isQuote && ((expecting & STARTQUOTE) > 0))
            {
                sb.append(c);
                expecting = CHAR | ENDQUOTE;
            }
            else if (isQuote && ((expecting & ENDQUOTE) > 0))
            {
                sb.append(c);
                expecting = (CHAR | STARTQUOTE | DELIMITER);
            }
            else if ((expecting & CHAR) > 0)
            {
                sb.append(c);
            }
            else
            {
                throw new IllegalArgumentException("Invalid delimited string: " + value);
            }
        }

        String s = sb.toString().trim();
        if (s.length() > 0)
        {
            list.add(s);
        }

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