/*
 *  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.tomcat.util.http;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.tomcat.util.buf.B2CConverter;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.buf.UDecoder;
import org.apache.tomcat.util.res.StringManager;

/**
 * 
 * @author Costin Manolache
 */
public final class Parameters {

    private static final org.apache.commons.logging.Log log =
            org.apache.commons.logging.LogFactory.getLog(Parameters.class);

    protected static final StringManager sm =
        StringManager.getManager("org.apache.tomcat.util.http");

    // HashMap<String,ArrayList<String>>
    private final HashMap paramHashValues = new HashMap();

    private boolean didQueryParameters=false;
    
    MessageBytes queryMB;

    UDecoder urlDec;
    MessageBytes decodedQuery=MessageBytes.newInstance();

    String encoding=null;
    String queryStringEncoding=null;

    private int limit = -1;
    private int parameterCount = 0;

    /**
     * Is set to <code>true</code> if there were failures during parameter
     * parsing.
     */
    private boolean parseFailed = false;

    public Parameters() {
        // NO-OP
    }

    public void setQuery( MessageBytes queryMB ) {
        this.queryMB=queryMB;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }

    public String getEncoding() {
        return encoding;
    }

    public void setEncoding( String s ) {
        encoding=s;
        if(log.isDebugEnabled()) {
            log.debug( "Set encoding to " + s );
        }
    }

    public void setQueryStringEncoding( String s ) {
        queryStringEncoding=s;
        if(log.isDebugEnabled()) {
            log.debug( "Set query string encoding to " + s );
        }
    }

    public boolean isParseFailed() {
        return parseFailed;
    }

    public void setParseFailed(boolean parseFailed) {
        this.parseFailed = parseFailed;
    }

    public void recycle() {
        parameterCount = 0;
        paramHashValues.clear();
        didQueryParameters=false;
        encoding=null;
        decodedQuery.recycle();
        parseFailed = false;
    }

    // -------------------- Data access --------------------
    // Access to the current name/values, no side effect ( processing ).
    // You must explicitly call handleQueryParameters and the post methods.
    
    public void addParameterValues(String key, String[] newValues) {
        if (key == null) {
            return;
        }
        ArrayList values = (ArrayList) paramHashValues.get(key);
        if (values == null) {
            values = new ArrayList(newValues.length);
            paramHashValues.put(key, values);
        } else {
            values.ensureCapacity(values.size() + newValues.length);
        }
        for (int i = 0; i < newValues.length; i++) {
            values.add(newValues[i]);
        }
    }

    public String[] getParameterValues(String name) {
        handleQueryParameters();
        // no "facade"
        ArrayList values = (ArrayList) paramHashValues.get(name);
        if (values == null) {
            return null;
        }
        return (String[]) values.toArray(new String[values.size()]);
    }
 
    public Enumeration getParameterNames() {
        handleQueryParameters();
        return Collections.enumeration(paramHashValues.keySet());
    }

    // Shortcut.
    public String getParameter(String name ) {
        handleQueryParameters();
        ArrayList values = (ArrayList) paramHashValues.get(name);
        if (values != null) {
            if(values.size() == 0) {
                return "";
            }
            return (String) values.get(0);
        } else {
            return null;
        }
    }
    // -------------------- Processing --------------------
    /** Process the query string into parameters
     */
    public void handleQueryParameters() {
        if( didQueryParameters ) return;

        didQueryParameters=true;

        if( queryMB==null || queryMB.isNull() )
            return;
        
        if(log.isDebugEnabled()) {
            log.debug("Decoding query " + decodedQuery + " " +
                    queryStringEncoding);
        }

        try {
            decodedQuery.duplicate( queryMB );
        } catch (IOException e) {
            // Can't happen, as decodedQuery can't overflow
            e.printStackTrace();
        }
        processParameters( decodedQuery, queryStringEncoding );
    }


    private void addParam( String key, String value ) {
        if( key==null ) return;
        ArrayList values = (ArrayList) paramHashValues.get(key);
        if (values == null) {
            values = new ArrayList(1);
            paramHashValues.put(key, values);
        }
        values.add(value);
    }

    public void setURLDecoder( UDecoder u ) {
        urlDec=u;
    }

    // -------------------- Parameter parsing --------------------
    // we are called from a single thread - we can do it the hard way
    // if needed
    ByteChunk tmpName=new ByteChunk();
    ByteChunk tmpValue=new ByteChunk();
    private ByteChunk origName=new ByteChunk();
    private ByteChunk origValue=new ByteChunk();
    private static final String DEFAULT_ENCODING = "ISO-8859-1";
    private static final Charset DEFAULT_CHARSET =
        Charset.forName(DEFAULT_ENCODING);
    
    
    public void processParameters( byte bytes[], int start, int len ) {
        processParameters(bytes, start, len, getCharset(encoding));
    }

    private void processParameters(byte bytes[], int start, int len,
                                  Charset charset) {
        
        if(log.isDebugEnabled()) {
            try {
                log.debug(sm.getString("parameters.bytes",
                        new String(bytes, start, len, DEFAULT_CHARSET.name())));
            } catch (UnsupportedEncodingException uee) {
                // Not possible. All JVMs must support ISO-8859-1
            }
        }

        int decodeFailCount = 0;
            
        int pos = start;
        int end = start + len;

        while(pos < end) {
            parameterCount ++;

            if (limit > -1 && parameterCount >= limit) {
                parseFailed = true;
                log.warn(sm.getString("parameters.maxCountFail",
                        Integer.toString(limit)));
                break;
            }
            int nameStart = pos;
            int nameEnd = -1;
            int valueStart = -1;
            int valueEnd = -1;

            boolean parsingName = true;
            boolean decodeName = false;
            boolean decodeValue = false;
            boolean parameterComplete = false;

            do {
                switch(bytes[pos]) {
                    case '=':
                        if (parsingName) {
                            // Name finished. Value starts from next character
                            nameEnd = pos;
                            parsingName = false;
                            valueStart = ++pos;
                        } else {
                            // Equals character in value
                            pos++;
                        }
                        break;
                    case '&':
                        if (parsingName) {
                            // Name finished. No value.
                            nameEnd = pos;
                        } else {
                            // Value finished
                            valueEnd  = pos;
                        }
                        parameterComplete = true;
                        pos++;
                        break;
                    case '%':
                    case '+':
                        // Decoding required
                        if (parsingName) {
                            decodeName = true;
                        } else {
                            decodeValue = true;
                        }
                        pos ++;
                        break;
                    default:
                        pos ++;
                        break;
                }
            } while (!parameterComplete && pos < end);

            if (pos == end) {
                if (nameEnd == -1) {
                    nameEnd = pos;
                } else if (valueStart > -1 && valueEnd == -1){
                    valueEnd = pos;
                }
            }
            
            if (log.isDebugEnabled() && valueStart == -1) {
                try {
                    log.debug(sm.getString("parameters.noequal",
                            Integer.toString(nameStart),
                            Integer.toString(nameEnd),
                            new String(bytes, nameStart, nameEnd-nameStart,
                                    DEFAULT_CHARSET.name())));
                } catch (UnsupportedEncodingException uee) {
                    // Not possible. All JVMs must support ISO-8859-1
                }
            }
            
            if (nameEnd <= nameStart ) {
                if (log.isInfoEnabled()) {
                    if (valueEnd >= nameStart && log.isDebugEnabled()) {
                        String extract = null;
                        try {
                            extract = new String(bytes, nameStart,
                                    valueEnd - nameStart,
                                    DEFAULT_CHARSET.name());
                        } catch (UnsupportedEncodingException uee) {
                            // Not possible. All JVMs must support ISO-8859-1
                        }
                        log.info(sm.getString("parameters.invalidChunk",
                                Integer.toString(nameStart),
                                Integer.toString(valueEnd),
                                extract));
                    } else {
                        log.info(sm.getString("parameters.invalidChunk",
                                Integer.toString(nameStart),
                                Integer.toString(nameEnd),
                                null));
                    }
                }
                parseFailed = true;
                continue;
                // invalid chunk - it's better to ignore
            }
            
            tmpName.setBytes(bytes, nameStart, nameEnd - nameStart);
            tmpValue.setBytes(bytes, valueStart, valueEnd - valueStart);

            // Take copies as if anything goes wrong originals will be
            // corrupted. This means original values can be logged.
            // For performance - only done for debug
            if (log.isDebugEnabled()) {
                try {
                    origName.append(bytes, nameStart, nameEnd - nameStart);
                    origValue.append(bytes, valueStart, valueEnd - valueStart);
                } catch (IOException ioe) {
                    // Should never happen...
                    log.error(sm.getString("paramerers.copyFail"), ioe);
                }
            }
            
            try {
                String name;
                String value;

                if (decodeName) {
                    urlDecode(tmpName);
                }
                tmpName.setCharset(charset);
                name = tmpName.toString();

                if (decodeValue) {
                    urlDecode(tmpValue);
                }
                tmpValue.setCharset(charset);
                value = tmpValue.toString();

                addParam(name, value);
            } catch (IOException e) {
                parseFailed = true;
                decodeFailCount++;
                if (decodeFailCount == 1 || log.isDebugEnabled()) {
                    if (log.isDebugEnabled()) {
                        log.debug(sm.getString("parameters.decodeFail.debug",
                                origName.toString(), origValue.toString()), e);
                    } else if (log.isInfoEnabled()) {
                        log.info(sm.getString("parameters.decodeFail.info",
                                tmpName.toString(), tmpValue.toString()), e);
                    }
                }
            }

            tmpName.recycle();
            tmpValue.recycle();
            // Only recycle copies if we used them
            if (log.isDebugEnabled()) {
                origName.recycle();
                origValue.recycle();
            }
        }

        if (decodeFailCount > 1 && !log.isDebugEnabled()) {
            log.info(sm.getString("parameters.multipleDecodingFail",
                    Integer.toString(decodeFailCount)));
        }
    }

    private void urlDecode(ByteChunk bc)
        throws IOException {
        if( urlDec==null ) {
            urlDec=new UDecoder();   
        }
        urlDec.convert(bc);
    }

    public void processParameters( MessageBytes data, String encoding ) {
        if( data==null || data.isNull() || data.getLength() <= 0 ) return;

        if( data.getType() != MessageBytes.T_BYTES ) {
            data.toBytes();
        }
        ByteChunk bc=data.getByteChunk();
        processParameters( bc.getBytes(), bc.getOffset(),
                           bc.getLength(), getCharset(encoding));
    }

    private Charset getCharset(String encoding) {
        if (encoding == null) {
            return DEFAULT_CHARSET;
        }
        try {
            return B2CConverter.getCharset(encoding);
        } catch (UnsupportedEncodingException e) {
            return DEFAULT_CHARSET;
        }
    }

    /**
     * Debug purpose
     */
    public String paramsAsString() {
        StringBuffer sb = new StringBuffer();
        Iterator it = paramHashValues.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
            sb.append(e.getKey()).append('=');
            ArrayList values = (ArrayList) e.getValue();
            for(int i = 0; i < values.size(); i++) {
                sb.append(values.get(i)).append(',');
            }
            sb.append('\n');
        }
        return sb.toString();
    }

}
