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

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.Map;
import java.util.TreeMap;
import javax.xml.transform.stream.StreamSource;

import org.apache.camel.BytesSource;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.StreamCache;
import org.apache.camel.StringSource;
import org.apache.camel.WrappedFile;

/**
 * Some helper methods when working with {@link org.apache.camel.Message}.
 * 
 * @version
 */
public final class MessageHelper {

    /**
     * Utility classes should not have a public constructor.
     */
    private MessageHelper() {
    }

    /**
     * Extracts the given body and returns it as a String, that can be used for
     * logging etc.
     * <p/>
     * Will handle stream based bodies wrapped in StreamCache.
     * 
     * @param message the message with the body
     * @return the body as String, can return <tt>null</null> if no body
     */
    public static String extractBodyAsString(Message message) {
        if (message == null) {
            return null;
        }

        StreamCache newBody = message.getBody(StreamCache.class);
        if (newBody != null) {
            message.setBody(newBody);
        }

        Object answer = message.getBody(String.class);
        if (answer == null) {
            answer = message.getBody();
        }

        if (newBody != null) {
            // Reset the InputStreamCache
            newBody.reset();
        }

        return answer != null ? answer.toString() : null;
    }

    /**
     * Gets the given body class type name as a String.
     * <p/>
     * Will skip java.lang. for the build in Java types.
     * 
     * @param message the message with the body
     * @return the body type name as String, can return
     *         <tt>null</null> if no body
     */
    public static String getBodyTypeName(Message message) {
        if (message == null) {
            return null;
        }
        String answer = ObjectHelper.classCanonicalName(message.getBody());
        if (answer != null && answer.startsWith("java.lang.")) {
            return answer.substring(10);
        }
        return answer;
    }

    /**
     * If the message body contains a {@link StreamCache} instance, reset the
     * cache to enable reading from it again.
     * 
     * @param message the message for which to reset the body
     */
    public static void resetStreamCache(Message message) {
        if (message == null) {
            return;
        }
        if (message.getBody() instanceof StreamCache) {
            ((StreamCache)message.getBody()).reset();
        }
    }

    /**
     * Returns the MIME content type on the message or <tt>null</tt> if none
     * defined
     */
    public static String getContentType(Message message) {
        return message.getHeader(Exchange.CONTENT_TYPE, String.class);
    }

    /**
     * Returns the MIME content encoding on the message or <tt>null</tt> if none
     * defined
     */
    public static String getContentEncoding(Message message) {
        return message.getHeader(Exchange.CONTENT_ENCODING, String.class);
    }

    /**
     * Extracts the body for logging purpose.
     * <p/>
     * Will clip the body if its too big for logging. Will prepend the message
     * with <tt>Message: </tt>
     * 
     * @see org.apache.camel.Exchange#LOG_DEBUG_BODY_STREAMS
     * @see org.apache.camel.Exchange#LOG_DEBUG_BODY_MAX_CHARS
     * @param message the message
     * @return the logging message
     */
    public static String extractBodyForLogging(Message message) {
        return extractBodyForLogging(message, "Message: ");
    }

    /**
     * Extracts the body for logging purpose.
     * <p/>
     * Will clip the body if its too big for logging.
     * 
     * @see org.apache.camel.Exchange#LOG_DEBUG_BODY_STREAMS
     * @see org.apache.camel.Exchange#LOG_DEBUG_BODY_MAX_CHARS
     * @param message the message
     * @param prepend a message to prepend
     * @return the logging message
     */
    public static String extractBodyForLogging(Message message, String prepend) {
        boolean streams = false;
        if (message.getExchange() != null) {
            String property = message.getExchange().getContext().getProperty(Exchange.LOG_DEBUG_BODY_STREAMS);
            if (property != null) {
                streams = message.getExchange().getContext().getTypeConverter().convertTo(Boolean.class, message.getExchange(), property);
            }
        }

        // default to 1000 chars
        int maxChars = 1000;

        if (message.getExchange() != null) {
            String property = message.getExchange().getContext().getProperty(Exchange.LOG_DEBUG_BODY_MAX_CHARS);
            if (property != null) {
                maxChars = message.getExchange().getContext().getTypeConverter().convertTo(Integer.class, property);
            }
        }

        return extractBodyForLogging(message, prepend, streams, false, maxChars);
    }

    /**
     * Extracts the body for logging purpose.
     * <p/>
     * Will clip the body if its too big for logging.
     * 
     * @see org.apache.camel.Exchange#LOG_DEBUG_BODY_MAX_CHARS
     * @param message the message
     * @param prepend a message to prepend
     * @param allowStreams whether or not streams is allowed
     * @param allowFiles whether or not files is allowed
     * @param maxChars limit to maximum number of chars. Use 0 or negative value
     *            to not limit at all.
     * @return the logging message
     */
    public static String extractBodyForLogging(Message message, String prepend, boolean allowStreams, boolean allowFiles, int maxChars) {
        Object obj = message.getBody();
        if (obj == null) {
            return prepend + "[Body is null]";
        }

        if (!allowStreams) {
            if (obj instanceof StreamSource && !(obj instanceof StringSource || obj instanceof BytesSource)) {
                /*
                 * Generally do not log StreamSources but as StringSource and
                 * ByteSource are memory based they are ok
                 */
                return prepend + "[Body is instance of java.xml.transform.StreamSource]";
            } else if (obj instanceof StreamCache) {
                return prepend + "[Body is instance of org.apache.camel.StreamCache]";
            } else if (obj instanceof InputStream) {
                return prepend + "[Body is instance of java.io.InputStream]";
            } else if (obj instanceof OutputStream) {
                return prepend + "[Body is instance of java.io.OutputStream]";
            } else if (obj instanceof Reader) {
                return prepend + "[Body is instance of java.io.Reader]";
            } else if (obj instanceof Writer) {
                return prepend + "[Body is instance of java.io.Writer]";
            } else if (obj instanceof WrappedFile || obj instanceof File) {
                return prepend + "[Body is file based: " + obj + "]";
            }
        }

        // is the body a stream cache
        StreamCache cache;
        if (obj instanceof StreamCache) {
            cache = (StreamCache)obj;
        } else {
            cache = null;
        }

        // grab the message body as a string
        String body = null;
        if (message.getExchange() != null) {
            try {
                body = message.getExchange().getContext().getTypeConverter().convertTo(String.class, message.getExchange(), obj);
            } catch (Exception e) {
                // ignore as the body is for logging purpose
            }
        }
        if (body == null) {
            body = obj.toString();
        }

        // reset stream cache after use
        if (cache != null) {
            cache.reset();
        }

        if (body == null) {
            return prepend + "[Body is null]";
        }

        // clip body if length enabled and the body is too big
        if (maxChars > 0 && body.length() > maxChars) {
            body = body.substring(0, maxChars) + "... [Body clipped after " + maxChars + " chars, total length is " + body.length() + "]";
        }

        return prepend + body;
    }

    /**
     * Dumps the message as a generic XML structure.
     * 
     * @param message the message
     * @return the XML
     */
    public static String dumpAsXml(Message message) {
        return dumpAsXml(message, true);
    }

    /**
     * Dumps the message as a generic XML structure.
     * 
     * @param message the message
     * @param includeBody whether or not to include the message body
     * @return the XML
     */
    public static String dumpAsXml(Message message, boolean includeBody) {
        return dumpAsXml(message, includeBody, 0);
    }

    /**
     * Dumps the message as a generic XML structure.
     *
     * @param message the message
     * @param includeBody whether or not to include the message body
     * @param indent number of spaces to indent
     * @return the XML
     */
    public static String dumpAsXml(Message message, boolean includeBody, int indent) {
        return dumpAsXml(message, includeBody, indent, false, true, 128 * 1024);
    }

    /**
     * Dumps the message as a generic XML structure.
     *
     * @param message the message
     * @param includeBody whether or not to include the message body
     * @param indent number of spaces to indent
     * @param allowStreams whether to include message body if they are stream based
     * @param allowFiles whether to include message body if they are file based
     * @param maxChars clip body after maximum chars (to avoid very big messages). Use 0 or negative value to not limit at all.
     * @return the XML
     */
    public static String dumpAsXml(Message message, boolean includeBody, int indent, boolean allowStreams, boolean allowFiles, int maxChars) {
        StringBuilder sb = new StringBuilder();

        StringBuilder prefix = new StringBuilder();
        for (int i = 0; i < indent; i++) {
            prefix.append(" ");
        }

        // include exchangeId as attribute on the <message> tag
        sb.append(prefix);
        sb.append("<message exchangeId=\"").append(message.getExchange().getExchangeId()).append("\">\n");

        // headers
        if (message.hasHeaders()) {
            sb.append(prefix);
            sb.append("  <headers>\n");
            // sort the headers so they are listed A..Z
            Map<String, Object> headers = new TreeMap<String, Object>(message.getHeaders());
            for (Map.Entry<String, Object> entry : headers.entrySet()) {
                Object value = entry.getValue();
                String type = ObjectHelper.classCanonicalName(value);
                sb.append(prefix);
                sb.append("    <header key=\"" + entry.getKey() + "\"");
                if (type != null) {
                    sb.append(" type=\"" + type + "\"");
                }
                sb.append(">");

                // dump header value as XML, use Camel type converter to convert
                // to String
                if (value != null) {
                    try {
                        String xml = message.getExchange().getContext().getTypeConverter().convertTo(String.class, 
                                message.getExchange(), value);
                        if (xml != null) {
                            // must always xml encode
                            sb.append(StringHelper.xmlEncode(xml));
                        }
                    } catch (Exception e) {
                        // ignore as the body is for logging purpose
                    }
                }

                sb.append("</header>\n");
            }
            sb.append(prefix);
            sb.append("  </headers>\n");
        }

        if (includeBody) {
            sb.append(prefix);
            sb.append("  <body");
            String type = ObjectHelper.classCanonicalName(message.getBody());
            if (type != null) {
                sb.append(" type=\"" + type + "\"");
            }
            sb.append(">");

            String xml = extractBodyForLogging(message, "", allowStreams, allowFiles, maxChars);
            if (xml != null) {
                // must always xml encode
                sb.append(StringHelper.xmlEncode(xml));
            }

            sb.append("</body>\n");
        }

        sb.append(prefix);
        sb.append("</message>");
        return sb.toString();
    }

    /**
     * Copies the headers from the source to the target message.
     * 
     * @param source the source message
     * @param target the target message
     * @param override whether to override existing headers
     */
    public static void copyHeaders(Message source, Message target, boolean override) {
        if (!source.hasHeaders()) {
            return;
        }

        for (Map.Entry<String, Object> entry : source.getHeaders().entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (target.getHeader(key) == null || override) {
                target.setHeader(key, value);
            }
        }
    }

}
