/*
 * 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.
 *
 * Contributors:
 *     Original contributors from geronimo-javamail_1.4_spec-1.7.1
 *     Florent Guillaume
 */
package org.apache.chemistry.opencmis.commons.impl;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;

/**
 * MIME helper class.
 */
public final class MimeHelper {

    public static final String CONTENT_DISPOSITION = "Content-Disposition";

    public static final String DISPOSITION_ATTACHMENT = "attachment";

    public static final String DISPOSITION_INLINE = "inline";

    public static final String DISPOSITION_FILENAME = "filename";

    public static final String DISPOSITION_NAME = "name";

    public static final String DISPOSITION_FORM_DATA_CONTENT = "form-data; " + DISPOSITION_NAME + "=\"content\"";

    // RFC 2045
    private static final String MIME_SPECIALS = "()<>@,;:\\\"/[]?=" + "\t ";

    private static final String RFC2231_SPECIALS = "*'%" + MIME_SPECIALS;

    private static final String WHITE = " \t\n\r";

    private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();

    private static final byte[] HEX_DECODE = new byte[0x80];
    static {
        for (int i = 0; i < HEX_DIGITS.length; i++) {
            HEX_DECODE[HEX_DIGITS[i]] = (byte) i;
            HEX_DECODE[Character.toLowerCase(HEX_DIGITS[i])] = (byte) i;
        }
    }

    private MimeHelper() {
    }

    /**
     * Encodes a value per RFC 2231.
     * <p>
     * This is used to pass non-ASCII parameters to MIME parameter lists.
     * <p>
     * This implementation always uses UTF-8 and no language.
     * <p>
     * See <a href="https://tools.ietf.org/html/rfc2231">RFC 2231</a> for
     * details.
     * 
     * @param value
     *            the value to encode
     * @param buf
     *            the buffer to fill
     * @return {@code true} if an encoding was needed, or {@code false} if no
     *         encoding was actually needed
     */
    protected static boolean encodeRFC2231value(String value, StringBuilder buf) {
        assert value != null;
        assert buf != null;

        String charset = IOUtils.UTF8;
        buf.append(charset);
        buf.append("''"); // no language
        byte[] bytes = IOUtils.toUTF8Bytes(value);

        boolean encoded = false;
        for (int i = 0; i < bytes.length; i++) {
            int ch = bytes[i] & 0xff;
            if (ch <= 32 || ch >= 127 || RFC2231_SPECIALS.indexOf(ch) != -1) {
                buf.append('%');
                buf.append(HEX_DIGITS[ch >> 4]);
                buf.append(HEX_DIGITS[ch & 0xf]);
                encoded = true;
            } else {
                buf.append((char) ch);
            }
        }
        return encoded;
    }

    /**
     * Encodes a MIME parameter per RFC 2231.
     * <p>
     * This implementation always uses UTF-8 and no language.
     * <p>
     * See <a href="https://tools.ietf.org/html/rfc2231">RFC 2231</a> for
     * details.
     * 
     * @param value
     *            the string to encode
     * @return the encoded string
     */
    protected static String encodeRFC2231(String key, String value) {
        StringBuilder buf = new StringBuilder(32);
        boolean encoded = encodeRFC2231value(value, buf);
        if (encoded) {
            return "; " + key + "*=" + buf.toString();
        } else {
            return "; " + key + "=" + value;
        }
    }

    /**
     * Encodes the Content-Disposition header value according to RFC 2183 and
     * RFC 2231.
     * <p>
     * See <a href="https://tools.ietf.org/html/rfc2231">RFC 2231</a> for
     * details.
     * 
     * @param disposition
     *            the disposition
     * @param filename
     *            the file name
     * @return the encoded header value
     */
    public static String encodeContentDisposition(String disposition, String filename) {
        if (disposition == null) {
            disposition = DISPOSITION_ATTACHMENT;
        }
        return disposition + encodeRFC2231(DISPOSITION_FILENAME, filename);
    }

    /**
     * Decodes a filename from the Content-Disposition header value according to
     * RFC 2183 and RFC 2231.
     * <p>
     * See <a href="https://tools.ietf.org/html/rfc2231">RFC 2231</a> for
     * details.
     * 
     * @param value
     *            the header value to decode
     * @return the filename
     */
    public static String decodeContentDispositionFilename(String value) {
        Map<String, String> params = new HashMap<String, String>();
        decodeContentDisposition(value, params);
        return params.get(DISPOSITION_FILENAME);
    }

    /**
     * Decodes the Content-Disposition header value according to RFC 2183 and
     * RFC 2231.
     * <p>
     * Does not deal with continuation lines.
     * <p>
     * See <a href="https://tools.ietf.org/html/rfc2231">RFC 2231</a> for
     * details.
     * 
     * @param value
     *            the header value to decode
     * @param params
     *            the map of parameters to fill
     * @return the disposition
     * 
     */
    public static String decodeContentDisposition(String value, Map<String, String> params) {
        try {
            HeaderTokenizer tokenizer = new HeaderTokenizer(value);
            // get the first token, which must be an ATOM
            Token token = tokenizer.next();
            if (token.getType() != Token.ATOM) {
                return null;
            }
            String disposition = token.getValue();
            // value ignored in this method

            // the remainder is the parameters
            String remainder = tokenizer.getRemainder();
            if (remainder != null) {
                getParameters(remainder, params);
            }
            return disposition;
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * Gets charset from a content type header.
     * 
     * @param value
     *            the header value to decode
     * @return the charset or <code>null</code> if no valid boundary available
     */
    public static String getCharsetFromContentType(String value) {
        try {
            HeaderTokenizer tokenizer = new HeaderTokenizer(value, ";", true);

            // get the first token, which must be an ATOM
            Token token = tokenizer.next();
            if (token.getType() != Token.ATOM) {
                return null;
            }

            // the remainder is the parameters
            String remainder = tokenizer.getRemainder();
            Map<String, String> params;
            if (remainder != null) {
                params = new HashMap<String, String>();
                getParameters(remainder, params);

                return params.get("charset");
            }
        } catch (ParseException e) {
            return null;
        }

        return null;
    }

    /**
     * Parses a WWW-Authenticate header value.
     * 
     * @param value
     *            the header value to parse
     * 
     * @return a map with the (lower case) challenge name as key and as the
     *         value a sub-map with parameters of the challenge
     */
    public static Map<String, Map<String, String>> getChallengesFromAuthenticateHeader(String value) {
        if (value == null || value.length() == 0) {
            return null;
        }

        final String trimValue = value.trim();

        Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();

        boolean inQuotes = false;
        boolean inName = true;
        String challenge = null;
        String paramName = "";
        StringBuilder sb = new StringBuilder(64);
        for (int i = 0; i < trimValue.length(); i++) {
            char c = trimValue.charAt(i);

            if (c == '\\') {
                if (!inQuotes) {
                    return null;
                }
                if (trimValue.length() > i && trimValue.charAt(i + 1) == '\\') {
                    sb.append('\\');
                    i++;
                } else if (trimValue.length() > i && trimValue.charAt(i + 1) == '"') {
                    sb.append('"');
                    i++;
                } else {
                    return null;
                }
            } else if (c == '"') {
                if (inName) {
                    return null;
                }
                if (inQuotes) {
                    Map<String, String> authMap = result.get(challenge);
                    if (authMap == null) {
                        return null;
                    }
                    authMap.put(paramName, sb.toString());
                }
                sb.setLength(0);
                inQuotes = !inQuotes;
            } else if (c == '=') {
                if (inName) {
                    paramName = sb.toString().trim();

                    int spcIdx = paramName.indexOf(' ');
                    if (spcIdx > -1) {
                        challenge = paramName.substring(0, spcIdx).toLowerCase(Locale.ENGLISH);
                        result.put(challenge, new HashMap<String, String>());
                        paramName = paramName.substring(spcIdx).trim();
                    }

                    sb.setLength(0);
                    inName = false;
                } else if (!inQuotes) {
                    return null;
                }
            } else if (c == ',') {
                if (inName) {
                    challenge = sb.toString().trim().toLowerCase(Locale.ENGLISH);
                    result.put(challenge, new HashMap<String, String>());
                    sb.setLength(0);
                } else {
                    if (inQuotes) {
                        sb.append(c);
                    } else {
                        Map<String, String> authMap = result.get(challenge);
                        if (authMap == null) {
                            return null;
                        }
                        if (!authMap.containsKey(paramName)) {
                            authMap.put(paramName, sb.toString().trim());
                        }
                        sb.setLength(0);
                        inName = true;
                    }
                }
            } else {
                sb.append(c);
            }
        }
        if (inQuotes) {
            return null;
        }
        if (inName) {
            challenge = sb.toString().trim().toLowerCase(Locale.ENGLISH);
            result.put(challenge, new HashMap<String, String>());
        } else {
            Map<String, String> authMap = result.get(challenge);
            if (authMap == null) {
                return null;
            }
            if (!authMap.containsKey(paramName)) {
                authMap.put(paramName, sb.toString().trim());
            }
        }

        return result;
    }

    /**
     * Gets the boundary from a <code>multipart/formdata</code> content type
     * header.
     * 
     * @param value
     *            the header value to decode
     * @return the boundary as a byte array or <code>null</code> if no valid
     *         boundary available
     */
    public static byte[] getBoundaryFromMultiPart(String value) {
        try {
            HeaderTokenizer tokenizer = new HeaderTokenizer(value, ";", true);

            // get the first token, which must be an ATOM
            Token token = tokenizer.next();
            if (token.getType() != Token.ATOM) {
                return null;
            }

            // check content type
            String multipartContentType = token.getValue();
            if (multipartContentType == null
                    || !(multipartContentType.equalsIgnoreCase("multipart/form-data") || multipartContentType
                            .equalsIgnoreCase("multipart/related"))) {
                return null;
            }

            // the remainder is the parameters
            String remainder = tokenizer.getRemainder();
            if (remainder != null) {
                Map<String, String> params = new HashMap<String, String>();
                getParameters(remainder, params);

                String boundaryStr = params.get("boundary");
                if (boundaryStr != null && boundaryStr.length() > 0) {
                    try {
                        return boundaryStr.getBytes(IOUtils.ISO_8859_1);
                    } catch (UnsupportedEncodingException e) {
                        // shouldn't happen...
                        throw new CmisRuntimeException("Unsupported encoding 'ISO-8859-1'", e);
                    }
                }
            }
        } catch (ParseException e) {
            return null;
        }

        return null;
    }

    protected static class ParseException extends Exception {
        private static final long serialVersionUID = 1L;

        public ParseException() {
            super();
        }

        public ParseException(String message) {
            super(message);
        }
    }

    /*
     * From geronimo-javamail_1.4_spec-1.7.1. Token
     */
    protected static class Token {
        // Constant values from J2SE 1.4 API Docs (Constant values)
        public static final int ATOM = -1;

        public static final int COMMENT = -3;

        public static final int EOF = -4;

        public static final int QUOTEDSTRING = -2;

        private final int type;

        private final String value;

        public Token(int type, String value) {
            this.type = type;
            this.value = value;
        }

        public int getType() {
            return type;
        }

        public String getValue() {
            return value;
        }
    }

    /*
     * Tweaked from geronimo-javamail_1.4_spec-1.7.1. HeaderTokenizer
     */
    protected static class HeaderTokenizer {

        private static final Token EOF = new Token(Token.EOF, null);

        private final String header;

        private final String delimiters;

        private final boolean skipComments;

        private int pos;

        public HeaderTokenizer(String header) {
            this(header, MIME_SPECIALS, true);
        }

        protected HeaderTokenizer(String header, String delimiters, boolean skipComments) {
            this.header = header;
            this.delimiters = delimiters;
            this.skipComments = skipComments;
        }

        public String getRemainder() {
            return header.substring(pos);
        }

        public Token next() throws ParseException {
            return readToken();
        }

        /**
         * Read an ATOM token from the parsed header.
         * 
         * @return A token containing the value of the atom token.
         */
        private Token readAtomicToken() {
            // skip to next delimiter
            int start = pos;
            while (++pos < header.length()) {
                // break on the first non-atom character.
                char ch = header.charAt(pos);
                if (delimiters.indexOf(header.charAt(pos)) != -1 || ch < 32 || ch >= 127) {
                    break;
                }
            }
            return new Token(Token.ATOM, header.substring(start, pos));
        }

        /**
         * Read the next token from the header.
         * 
         * @return The next token from the header. White space is skipped, and
         *         comment tokens are also skipped if indicated.
         */
        private Token readToken() throws ParseException {
            if (pos >= header.length()) {
                return EOF;
            } else {
                char c = header.charAt(pos);
                // comment token...read and skip over this
                if (c == '(') {
                    Token comment = readComment();
                    if (skipComments) {
                        return readToken();
                    } else {
                        return comment;
                    }
                    // quoted literal
                } else if (c == '\"') {
                    return readQuotedString();
                    // white space, eat this and find a real token.
                } else if (WHITE.indexOf(c) != -1) {
                    eatWhiteSpace();
                    return readToken();
                    // either a CTL or special. These characters have a
                    // self-defining token type.
                } else if (c < 32 || c >= 127 || delimiters.indexOf(c) != -1) {
                    pos++;
                    return new Token(c, String.valueOf(c));
                } else {
                    // start of an atom, parse it off.
                    return readAtomicToken();
                }
            }
        }

        /**
         * Extract a substring from the header string and apply any
         * escaping/folding rules to the string.
         * 
         * @param start
         *            The starting offset in the header.
         * @param end
         *            The header end offset + 1.
         * @return The processed string value.
         */
        private String getEscapedValue(int start, int end) throws ParseException {
            StringBuilder value = new StringBuilder(32);
            for (int i = start; i < end; i++) {
                char ch = header.charAt(i);
                // is this an escape character?
                if (ch == '\\') {
                    i++;
                    if (i == end) {
                        throw new ParseException("Invalid escape character");
                    }
                    value.append(header.charAt(i));
                } else if (ch == '\r') {
                    // line breaks are ignored, except for naked '\n'
                    // characters, which are consider parts of linear
                    // whitespace.
                    // see if this is a CRLF sequence, and skip the second if it
                    // is.
                    if (i < end - 1 && header.charAt(i + 1) == '\n') {
                        i++;
                    }
                } else {
                    // just append the ch value.
                    value.append(ch);
                }
            }
            return value.toString();
        }

        /**
         * Read a comment from the header, applying nesting and escape rules to
         * the content.
         * 
         * @return A comment token with the token value.
         */
        private Token readComment() throws ParseException {
            int start = pos + 1;
            int nesting = 1;
            boolean requiresEscaping = false;
            // skip to end of comment/string
            while (++pos < header.length()) {
                char ch = header.charAt(pos);
                if (ch == ')') {
                    nesting--;
                    if (nesting == 0) {
                        break;
                    }
                } else if (ch == '(') {
                    nesting++;
                } else if (ch == '\\') {
                    pos++;
                    requiresEscaping = true;
                } else if (ch == '\r') {
                    // we need to process line breaks also
                    requiresEscaping = true;
                }
            }
            if (nesting != 0) {
                throw new ParseException("Unbalanced comments");
            }
            String value;
            if (requiresEscaping) {
                value = getEscapedValue(start, pos);
            } else {
                value = header.substring(start, pos++);
            }
            return new Token(Token.COMMENT, value);
        }

        /**
         * Parse out a quoted string from the header, applying escaping rules to
         * the value.
         * 
         * @return The QUOTEDSTRING token with the value.
         * @exception ParseException
         */
        private Token readQuotedString() throws ParseException {
            int start = pos + 1;
            boolean requiresEscaping = false;
            // skip to end of comment/string
            while (++pos < header.length()) {
                char ch = header.charAt(pos);
                if (ch == '"') {
                    String value;
                    if (requiresEscaping) {
                        value = getEscapedValue(start, pos++);
                    } else {
                        value = header.substring(start, pos++);
                    }
                    return new Token(Token.QUOTEDSTRING, value);
                } else if (ch == '\\') {
                    pos++;
                    requiresEscaping = true;
                } else if (ch == '\r') {
                    // we need to process line breaks also
                    requiresEscaping = true;
                }
            }
            throw new ParseException("Missing '\"'");
        }

        /**
         * Skip white space in the token string.
         */
        private void eatWhiteSpace() {
            // skip to end of whitespace
            while (++pos < header.length() && WHITE.indexOf(header.charAt(pos)) != -1) {
                // just read
            }
        }
    }

    /*
     * Tweaked from geronimo-javamail_1.4_spec-1.7.1. ParameterList
     */
    protected static Map<String, String> getParameters(String list, Map<String, String> params) throws ParseException {
        HeaderTokenizer tokenizer = new HeaderTokenizer(list);
        while (true) {
            Token token = tokenizer.next();
            switch (token.getType()) {
            case Token.EOF:
                // the EOF token terminates parsing.
                return params;

            case ';':
                // each new parameter is separated by a semicolon, including
                // the first, which separates
                // the parameters from the main part of the header.
                // the next token needs to be a parameter name
                token = tokenizer.next();
                // allow a trailing semicolon on the parameters.
                if (token.getType() == Token.EOF) {
                    return params;
                }

                if (token.getType() != Token.ATOM) {
                    throw new ParseException("Invalid parameter name: " + token.getValue());
                }

                // get the parameter name as a lower case version for better
                // mapping.
                String name = token.getValue().toLowerCase(Locale.ENGLISH);

                token = tokenizer.next();

                // parameters are name=value, so we must have the "=" here.
                if (token.getType() != '=') {
                    throw new ParseException("Missing '='");
                }

                // now the value, which may be an atom or a literal
                token = tokenizer.next();

                if (token.getType() != Token.ATOM && token.getType() != Token.QUOTEDSTRING) {
                    throw new ParseException("Invalid parameter value: " + token.getValue());
                }

                String value = token.getValue();

                // we might have to do some additional decoding. A name that
                // ends with "*" is marked as being encoded, so if requested, we
                // decode the value.
                if (name.endsWith("*")) {
                    name = name.substring(0, name.length() - 1);
                    value = decodeRFC2231value(value);
                }
                params.put(name, value);
                break;
            default:
                throw new ParseException("Missing ';'");
            }
        }
    }

    protected static String decodeRFC2231value(String value) {
        int q1 = value.indexOf('\'');
        if (q1 == -1) {
            // missing charset
            return value;
        }
        String mimeCharset = value.substring(0, q1);
        int q2 = value.indexOf('\'', q1 + 1);
        if (q2 == -1) {
            // missing language
            return value;
        }
        byte[] bytes = fromHex(value.substring(q2 + 1));
        try {
            return new String(bytes, getJavaCharset(mimeCharset));
        } catch (UnsupportedEncodingException e) {
            // incorrect encoding
            return value;
        }
    }

    protected static byte[] fromHex(String data) {
        ByteArrayOutputStream out = new ByteArrayOutputStream(data.length());
        for (int i = 0; i < data.length();) {
            char c = data.charAt(i++);
            if (c == '%') {
                if (i > data.length() - 2) {
                    break; // unterminated sequence
                }
                byte b1 = HEX_DECODE[data.charAt(i++) & 0x7f];
                byte b2 = HEX_DECODE[data.charAt(i++) & 0x7f];
                out.write((b1 << 4) | b2);
            } else {
                out.write((byte) c);
            }
        }
        return out.toByteArray();
    }

    protected static String getJavaCharset(String mimeCharset) {
        // good enough for standard values
        return mimeCharset;
    }

}
