/*
 *  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.asyncweb.common.codec;

import java.net.URI;
import java.util.List;
import java.util.Map;

import org.apache.asyncweb.common.DefaultHttpRequest;
import org.apache.asyncweb.common.HttpHeaderConstants;
import org.apache.asyncweb.common.HttpMethod;
import org.apache.asyncweb.common.HttpRequest;
import org.apache.asyncweb.common.HttpResponseStatus;
import org.apache.asyncweb.common.HttpVersion;
import org.apache.asyncweb.common.MutableHttpRequest;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.statemachine.CrLfDecodingState;
import org.apache.mina.filter.codec.statemachine.DecodingState;
import org.apache.mina.filter.codec.statemachine.DecodingStateMachine;
import org.apache.mina.filter.codec.statemachine.FixedLengthDecodingState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Parses HTTP requests.
 * Clients should register a <code>HttpRequestParserListener</code>
 * in order to receive notifications at important stages of request
 * building.<br/>
 *
 * <code>HttpRequestParser</code>s should not be built for each request
 * as each parser constructs an underlying state machine which is
 * relatively costly to build.<br/> Instead, parsers should be pooled.<br/>
 *
 * Note, however, that a parser <i>must</i> be <code>prepare</code>d before
 * each new parse.
 *
 * @author The Apache MINA Project (dev@mina.apache.org)
 * @version $Rev$, $Date$
 */
abstract class HttpRequestDecodingStateMachine extends DecodingStateMachine {

    private static final Logger LOG = LoggerFactory
            .getLogger(HttpRequestDecodingStateMachine.class);

    /**
     * The request we are building
     */
    private MutableHttpRequest request;

    @Override
    protected DecodingState init() throws Exception {
        request = new DefaultHttpRequest();
        return SKIP_EMPTY_LINES;
    }

    @Override
    protected void destroy() throws Exception {
        request = null;
    }

    private final DecodingState SKIP_EMPTY_LINES = new CrLfDecodingState() {

        @Override
        protected DecodingState finishDecode(boolean foundCRLF,
                ProtocolDecoderOutput out) throws Exception {
            if (foundCRLF) {
                return this;
            } else {
                return READ_REQUEST_LINE;
            }
        }
    };

    private final DecodingState READ_REQUEST_LINE = new HttpRequestLineDecodingState() {
        @Override
        protected DecodingState finishDecode(List<Object> childProducts,
                ProtocolDecoderOutput out) throws Exception {
            URI requestUri = (URI) childProducts.get(1);
            request.setMethod((HttpMethod) childProducts.get(0));
            request.setRequestUri(requestUri);
            request.setProtocolVersion((HttpVersion) childProducts.get(2));
            request.setParameters(requestUri.getRawQuery());
            return READ_HEADERS;
        }
    };

    private final DecodingState READ_HEADERS = new HttpHeaderDecodingState() {
        @Override
        @SuppressWarnings("unchecked")
        protected DecodingState finishDecode(List<Object> childProducts,
                ProtocolDecoderOutput out) throws Exception {
            Map<String, List<String>> headers =
                (Map<String, List<String>>) childProducts.get(0);
            
            // Set cookies.
            List<String> cookies = headers.get(
                    HttpHeaderConstants.KEY_COOKIE);
            if (cookies != null && !cookies.isEmpty()) {
                if (cookies.size() > 1) {
                    if (LOG.isWarnEnabled()) {
                        LOG.warn("Ignoring extra cookie headers: "
                                + cookies.subList(1, cookies.size()));
                    }
                }
                request.setCookies(cookies.get(0));
            }

            // Set headers.
            request.setHeaders(headers);

            if (LOG.isDebugEnabled()) {
                LOG.debug("Decoded header: " + request.getHeaders());
            }

            // Select appropriate body decoding state.
            boolean isChunked = false;
            if (request.getProtocolVersion() == HttpVersion.HTTP_1_1) {
                LOG.debug("Request is HTTP 1/1. Checking for transfer coding");
                isChunked = isChunked(request);
            } else {
                LOG.debug("Request is not HTTP 1/1. Using content length");
            }
            DecodingState nextState;
            if (isChunked) {
                LOG.debug("Using chunked decoder for request");
                nextState = new ChunkedBodyDecodingState() {
                    @Override
                    protected DecodingState finishDecode(
                            List<Object> childProducts,
                            ProtocolDecoderOutput out) throws Exception {
                        if (childProducts.size() != 1) {
                            int chunkSize = 0;
                            for (Object product : childProducts) {
                                IoBuffer chunk = (IoBuffer) product;
                                chunkSize += chunk.remaining();
                            }

                            IoBuffer body = IoBuffer.allocate(chunkSize);
                            for (Object product : childProducts) {
                                IoBuffer chunk = (IoBuffer) product;
                                body.put(chunk);
                            }
                            body.flip();
                            request.setContent(body);
                        } else {
                            request.setContent((IoBuffer) childProducts.get(0));
                        }

                        out.write(request);
                        return null;
                    }
                };
            } else {
                int length = getContentLength(request);
                if (length > 0) {
                    if (LOG.isDebugEnabled()) {
                        LOG
                                .debug("Using fixed length decoder for request with length "
                                        + length);
                    }
                    nextState = new FixedLengthDecodingState(length) {
                        @Override
                        protected DecodingState finishDecode(IoBuffer readData,
                                ProtocolDecoderOutput out) throws Exception {
                            request.setContent(readData);
                            out.write(request);
                            return null;
                        }
                    };
                } else {
                    LOG.debug("No entity body for this request");
                    out.write(request);
                    nextState = null;
                }
            }
            return nextState;
        }

        /**
         * Obtains the content length from the specified request
         *
         * @param request  The request
         * @return         The content length, or 0 if not specified
         * @throws HttpDecoderException If an invalid content length is specified
         */
        private int getContentLength(HttpRequest request)
                throws ProtocolDecoderException {
            int length = 0;
            String lengthValue = request.getHeader(
                    HttpHeaderConstants.KEY_CONTENT_LENGTH);
            if (lengthValue != null) {
                try {
                    length = Integer.parseInt(lengthValue);
                } catch (NumberFormatException e) {
                    HttpCodecUtils.throwDecoderException(
                            "Invalid content length: " + length,
                            HttpResponseStatus.BAD_REQUEST);
                }
            }
            return length;
        }

        /**
         * Determines whether a specified request employs a chunked
         * transfer coding
         *
         * @param request  The request
         * @return         <code>true</code> iff the request employs a
         *                 chunked transfer coding
         * @throws HttpDecoderException
         *                 If the request employs an unsupported coding
         */
        private boolean isChunked(HttpRequest request)
                throws ProtocolDecoderException {
            boolean isChunked = false;
            String coding = request.getHeader(
                    HttpHeaderConstants.KEY_TRANSFER_ENCODING);
            if (coding == null) {
                coding = request.getHeader(
                        HttpHeaderConstants.KEY_TRANSFER_CODING);
            }

            if (coding != null) {
                int extensionIndex = coding.indexOf(';');
                if (extensionIndex != -1) {
                    coding = coding.substring(0, extensionIndex);
                }
                if (HttpHeaderConstants.VALUE_CHUNKED.equalsIgnoreCase(coding)) {
                    isChunked = true;
                } else {
                    // As we only support chunked encoding, any other encoding
                    // is unsupported
                    HttpCodecUtils.throwDecoderException(
                            "Unknown transfer coding " + coding,
                            HttpResponseStatus.NOT_IMPLEMENTED);
                }
            }
            return isChunked;
        }
    };
}
