/**
 * 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.Exchange;
import org.apache.camel.Message;
import org.apache.camel.StreamCache;
import org.apache.camel.component.file.GenericFile;
import org.apache.camel.converter.jaxp.BytesSource;
import org.apache.camel.converter.jaxp.StringSource;

/**
 * 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 typename 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().getProperties().get(Exchange.LOG_DEBUG_BODY_STREAMS);
            if (property != null) {
                streams = message.getExchange().getContext().getTypeConverter().convertTo(Boolean.class, property);
            }
        }

        // default to 1000 chars
        int maxChars = 1000;

        if (message.getExchange() != null) {
            String property = message.getExchange().getContext().getProperties().get(Exchange.LOG_DEBUG_BODY_MAX_CHARS);
            if (property != null) {
                maxChars = message.getExchange().getContext().getTypeConverter().convertTo(Integer.class, property);
            }
        }
        return extractBodyForLogging(message, prepend, streams, 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 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, int maxChars) {
        Object obj = message.getBody();
        if (obj == null) {
            return prepend + "[Body is null]";
        }

        if (obj instanceof StringSource || obj instanceof BytesSource) {
            // these two are okay
        } else if (!allowStreams && obj instanceof StreamCache) {
            return prepend + "[Body is instance of org.apache.camel.StreamCache]";
        } else if (!allowStreams && obj instanceof StreamSource) {
            return prepend + "[Body is instance of java.xml.transform.StreamSource]";
        } else if (!allowStreams && obj instanceof InputStream) {
            return prepend + "[Body is instance of java.io.InputStream]";
        } else if (!allowStreams && obj instanceof OutputStream) {
            return prepend + "[Body is instance of java.io.OutputStream]";
        } else if (!allowStreams && obj instanceof Reader) {
            return prepend + "[Body is instance of java.io.Reader]";
        } else if (!allowStreams && obj instanceof Writer) {
            return prepend + "[Body is instance of java.io.Writer]";
        } else if (obj instanceof GenericFile || 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;
        if (message.getExchange() != null) {
            body = message.getExchange().getContext().getTypeConverter().convertTo(String.class, obj);
        } else {
            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) {
        StringBuilder sb = new StringBuilder();
        sb.append("<message>\n");

        // headers
        if (message.hasHeaders()) {
            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("<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) {
                    String xml = message.getExchange().getContext().getTypeConverter().convertTo(String.class, value);
                    if (xml != null) {
                        // is the header value already XML
                        if (xml.startsWith("<") && xml.endsWith(">")) {
                            sb.append(xml);
                        } else {
                            // no its not xml so xml encode it
                            sb.append(StringHelper.xmlEncode(xml));
                        }
                    }
                }

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

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

        // dump body value as XML, use Camel type converter to convert to String
        String xml = message.getBody(String.class);
        if (xml != null) {
            // is the body already XML
            if (xml.startsWith("<") && xml.endsWith(">")) {
                sb.append(xml);
            } else {
                // no its not xml so xml encode it
                sb.append(StringHelper.xmlEncode(xml));
            }
        }

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

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

}
