/*
 *  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.io.UnsupportedEncodingException;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.List;
import java.util.Map;

import org.apache.asyncweb.common.HttpMessage;
import org.apache.asyncweb.common.HttpResponseStatus;
import org.apache.asyncweb.common.HttpResponseStatus.Category;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author The Apache MINA Project (dev@mina.apache.org)
 * @version $Rev$, $Date$
 */
public class HttpCodecUtils {

    public static final String DEFAULT_CHARSET_NAME = "UTF-8";
    public static final Charset DEFAULT_CHARSET =
        Charset.forName(DEFAULT_CHARSET_NAME);
    public static final String US_ASCII_CHARSET_NAME = "US-ASCII";
    public static final Charset US_ASCII_CHARSET =
        Charset.forName(US_ASCII_CHARSET_NAME);
    public static final String DEFAULT_TIME_ZONE_NAME = "GMT";

    /**
     * Bytes making up a <code>CR LF</code>
     */
    private static final byte[] CRLF_BYTES = new byte[] { '\r', '\n' };

    /**
     * A lookup table for HTPP separator characters
     */
    private static boolean[] HTTP_SEPARATORS = new boolean[128];

    /**
     * A lookup table for HTTP control characters
     */
    private static boolean[] HTTP_CONTROLS = new boolean[128];

    /**
     * A lookup table from ASCII char values to corresponding decimal values
     */
    private static final int[] HEX_DEC = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, 00, 01, 02, 03, 04, 05, 06, 07, 8, 9, -1, -1,
            -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, };

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

    /**
     * Determines whether a specified (US-ASCII) character is a
     * valid hex character:
     * <ul>
     *   <li>A..F</li>
     *   <li>a..f</li>
     *   <li>0..9</li>
     * </ul>
     *
     * @param b  The character to check
     * @return  <code>true</code> iff the character is a valid hex
     *          character
     */
    static boolean isHex(byte b) {
        return HEX_DEC[b] != -1;
    }

    /**
     * Determines whether a specified (US-ASCII) character is an
     * HTTP field separator
     *
     * @param b  the US-ASCII character to check
     * @return   <code>true</code> iff the character is an HTTP field
     *           separator
     */
    public static boolean isHttpSeparator(byte b) {
        return HTTP_SEPARATORS[b];
    }

    /**
     * Determines whether a specified (US-ASCII) character is an
     * HTTP control character
     *
     * @param b  the US-ASCII character to check
     * @return   <code>true</code> iff the character is an HTTP control
     *           character
     */
    public static boolean isHttpControl(byte b) {
        return HTTP_CONTROLS[b];
    }

    /**
     * Throws a {@link HttpRequestDecoderException} with a specified cause.
     * This method should be used when the request is badly formed.
     *
     * @param cause  The cause
     */
    static void throwDecoderException(String cause)
            throws ProtocolDecoderException {
        throwDecoderException(cause, HttpResponseStatus.BAD_REQUEST);
    }

    /**
     * Throws a {@link HttpRequestDecoderException} with a specified response
     * status
     *
     * @param message   The cause
     * @param status  The response status
     */
    static void throwDecoderException(String message,
            HttpResponseStatus status) throws ProtocolDecoderException {
        if (!(status.getCategory() == HttpResponseStatus.Category.CLIENT_ERROR || status
                .getCategory() == HttpResponseStatus.Category.SERVER_ERROR)) {
            throw new IllegalArgumentException(
                    "Cant fail with successful response");
        }
        if (LOG.isInfoEnabled()) {
            LOG.info("Decode failure. Cause: " + message);
        }
        throw new HttpRequestDecoderException(message, status);
    }

    /**
     * Appends a string to a specified {@link IoBuffer}.
     * This method assumes ascii encoding and is primarily used for encoding
     * http header names and values.<br/>
     * Note that encoding header values this way is not stricly correct
     * (character encodings). However, existing containers do it this way
     * (e.g. Tomcat), and we're probably safer doing it a similar way for the
     * time being
     *
     * @param buffer  The buffer to append to
     * @param string  The string to append
     */
    static void appendString(IoBuffer buffer, String string) {
        if (string == null) {
            return;
        }
        int len = string.length();

        for (int i = 0; i < len; i++) {
            byte b = (byte) string.charAt(i);
            if (isHttpControl(b) && b != '\t') {
                b = ' ';
            }
            buffer.put(b);
        }
    }

    /**
     * Appends a <code>CR LF</code> to the specified buffer
     *
     * @param buffer  The buffer
     */
    static void appendCRLF(IoBuffer buffer) {
        buffer.put(CRLF_BYTES);
    }
    
    /**
     * Encodes the headers of a <code>Response</code> to a specified buffer.
     * This encoder does not make smart decisions about which headers to write -
     * the response is expected to already contain self-consistent headers.
     *
     * @param message  The response whose headers are to be encoded
     * @param buffer   The buffer
     */
    static void encodeHeaders(
            HttpMessage message, IoBuffer buffer, CharsetEncoder encoder) throws CharacterCodingException {
        
        try {
            for (Map.Entry<String, List<String>> header : message.getHeaders()
                    .entrySet()) {
                byte[] key = header.getKey().getBytes(
                        HttpCodecUtils.US_ASCII_CHARSET_NAME);

                for (String value : header.getValue()) {
                    buffer.put(key);
                    buffer.put((byte) ':');
                    buffer.put((byte) ' ');
                    buffer.putString(value, encoder);
                    HttpCodecUtils.appendCRLF(buffer);
                }
            }
        } catch (UnsupportedEncodingException e) {
            throw new InternalError(
                    HttpCodecUtils.US_ASCII_CHARSET_NAME + 
                    " should be available.");
        }

        HttpCodecUtils.appendCRLF(buffer);
    }

    /**
     * Writes the response body bytes, if any, to the specified buffer
     *
     * @param message  The response
     * @param buffer   The buffer to write to
     */
    static void encodeBody(HttpMessage message, IoBuffer buffer) {
        IoBuffer content = message.getContent();
        buffer.put(content);
    }

    static {
        // HTTP Separator characters
        HTTP_SEPARATORS[34] = true; // "
        HTTP_SEPARATORS[40] = true; // )
        HTTP_SEPARATORS[41] = true; // (
        HTTP_SEPARATORS[44] = true; // ,
        HTTP_SEPARATORS[47] = true; // /
        HTTP_SEPARATORS[58] = true; // :
        HTTP_SEPARATORS[59] = true; // ;
        HTTP_SEPARATORS[60] = true; // <
        HTTP_SEPARATORS[61] = true; // =
        HTTP_SEPARATORS[62] = true; // >
        HTTP_SEPARATORS[63] = true; // ?
        HTTP_SEPARATORS[64] = true; // @
        HTTP_SEPARATORS[91] = true; // [
        HTTP_SEPARATORS[93] = true; // ]
        HTTP_SEPARATORS[92] = true; // \
        HTTP_SEPARATORS[123] = true; // {
        HTTP_SEPARATORS[125] = true; // }

        // HTTP Control characters
        for (int i = 0; i <= 31; ++i) {
            HTTP_CONTROLS[i] = true;
        }
        HTTP_CONTROLS[127] = true; // DEL

    }
}
