/**
 * 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.activemq.openwire.commands;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectStreamException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;

import org.apache.activemq.openwire.annotations.OpenWireExtension;
import org.apache.activemq.openwire.annotations.OpenWireType;
import org.apache.activemq.openwire.codec.OpenWireFormat;
import org.apache.activemq.openwire.utils.IOExceptionSupport;
import org.apache.activemq.openwire.utils.OpenWireMarshallingSupport;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.ByteArrayInputStream;
import org.fusesource.hawtbuf.ByteArrayOutputStream;
import org.fusesource.hawtbuf.UTF8Buffer;

/**
 * openwire:marshaller code="25"
 */
@OpenWireType(typeCode = 25)
public class OpenWireMapMessage extends OpenWireMessage {

    public static final byte DATA_STRUCTURE_TYPE = CommandTypes.OPENWIRE_MAP_MESSAGE;

    @OpenWireExtension
    protected transient Map<String, Object> map = new HashMap<String, Object>();

    private Object readResolve() throws ObjectStreamException {
        if (this.map == null) {
            this.map = new HashMap<String, Object>();
        }
        return this;
    }

    @Override
    public OpenWireMapMessage copy() {
        OpenWireMapMessage copy = new OpenWireMapMessage();
        copy(copy);
        return copy;
    }

    private void copy(OpenWireMapMessage copy) {
        storeContent();
        super.copy(copy);
    }

    // We only need to marshal the content if we are hitting the wire.
    @Override
    public void beforeMarshall(OpenWireFormat wireFormat) throws IOException {
        super.beforeMarshall(wireFormat);
        storeContent();
    }

    @Override
    public void clearMarshalledState() throws IOException {
        super.clearMarshalledState();
        map.clear();
    }

    @Override
    public void storeContentAndClear() {
        storeContent();
        map.clear();
    }

    @Override
    public void storeContent() {
        try {
            if (getContent() == null && !map.isEmpty()) {
                ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
                OutputStream os = bytesOut;
                if (isUseCompression()) {
                    compressed = true;
                    os = new DeflaterOutputStream(os);
                }
                DataOutputStream dataOut = new DataOutputStream(os);
                OpenWireMarshallingSupport.marshalPrimitiveMap(map, dataOut);
                dataOut.close();
                setContent(bytesOut.toBuffer());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Builds the message body from data
     *
     * @throws IOException
     */
    private void loadContent() throws IOException {
        try {
            if (getContent() != null && map.isEmpty()) {
                Buffer content = getContent();
                InputStream is = new ByteArrayInputStream(content);
                if (isCompressed()) {
                    is = new InflaterInputStream(is);
                }
                DataInputStream dataIn = new DataInputStream(is);
                map = OpenWireMarshallingSupport.unmarshalPrimitiveMap(dataIn);
                dataIn.close();
            }
        } catch (Exception e) {
            throw IOExceptionSupport.create(e);
        }
    }

    @Override
    public byte getDataStructureType() {
        return DATA_STRUCTURE_TYPE;
    }

    @Override
    public String getMimeType() {
        return "jms/map-message";
    }

    /**
     * Clears out the message body. Clearing a message's body does not clear its
     * header values or property entries.
     * <P>
     * If this message body was read-only, calling this method leaves the
     * message body in the same state as an empty body in a newly created
     * message.
     */
    @Override
    public void clearBody() throws IOException {
        super.clearBody();
        map.clear();
    }

    /**
     * Returns the value of the object with the specified name.
     * <P>
     * This method can be used to return, in objectified format, an object in
     * the Java programming language ("Java object") that had been stored in the
     * Map with the equivalent <CODE>setObject</CODE> method call, or its
     * equivalent primitive <CODE>set <I>type </I></CODE> method.
     * <P>
     * Note that byte values are returned as <CODE>byte[]</CODE>, not
     * <CODE>Byte[]</CODE>.
     *
     * @param name
     *        the name of the Java object
     *
     * @return a copy of the Java object value with the specified name, in
     *         objectified format (for example, if the object was set as an
     *         <CODE>int</CODE>, an <CODE>Integer</CODE> is returned); if
     *         there is no item by this name, a null value is returned
     * @throws JMSException if the JMS provider fails to read the message due to
     *                 some internal error.
     */
    public Object getObject(String name) throws IOException {
        initializeReading();
        Object result = getContentMap().get(name);
        if (result instanceof UTF8Buffer) {
            result = result.toString();
        }

        return result;
    }

    /**
     * Sets an object value with the specified name into the Map.
     * <P>
     * This method works only for the objectified primitive object types
     * (<code>Integer</code>,<code>Double</code>,<code>Long</code> &nbsp;...),
     * <code>String</code> objects, and byte arrays.
     *
     * @param name
     *        the name of the Java object
     * @param value
     *        the Java object value to set in the Map
     * @throws JMSException if the JMS provider fails to write the message due
     *                      to some internal error.
     * @throws IllegalArgumentException if the name is null or if the name is an
     *                                  empty string.
     * @throws MessageFormatException if the object is invalid.
     */
    public void setObject(String name, Object value) throws IOException {
        initializeWriting();
        if (value != null) {
            // byte[] not allowed on properties
            if (!(value instanceof byte[])) {
                checkValidObject(value);
            }
            put(name, value);
        } else {
            put(name, null);
        }
    }

    /**
     * Removes an object value with the specified name into the Map.
     *
     * @param name
     *        the name of the Java object
     *
     * @throws JMSException if the JMS provider fails to write the message due
     *                      to some internal error.
     * @throws IllegalArgumentException if the name is null or if the name is an
     *                                  empty string.
     */
    public void removeObject(String name) throws IOException {
        initializeWriting();
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("map element name cannot be null or empty.");
        }

        this.map.remove(name);
    }

    /**
     * Returns an <CODE>Enumeration</CODE> of all the names in the
     * <CODE>MapMessage</CODE> object.
     *
     * @return an enumeration of all the names in this <CODE>MapMessage</CODE>
     * @throws JMSException
     */
    public Enumeration<String> getMapNames() throws IOException {
        return Collections.enumeration(getContentMap().keySet());
    }

    /**
     * Indicates whether an item exists in this <CODE>MapMessage</CODE>
     * object.
     *
     * @param name the name of the item to test
     * @return true if the item exists
     * @throws JMSException if the JMS provider fails to determine if the item
     *                 exists due to some internal error.
     */
    public boolean itemExists(String name) throws IOException {
        return getContentMap().containsKey(name);
    }

    private void initializeReading() throws IOException {
        loadContent();
    }

    private void initializeWriting() throws IOException {
        setContent(null);
    }

    @Override
    public void compress() throws IOException {
        storeContent();
        super.compress();
    }

    @Override
    public String toString() {
        return super.toString() + " OpenWireMapMessage{ " + "theTable = " + map + " }";
    }

    protected Map<String, Object> getContentMap() throws IOException {
        initializeReading();
        return map;
    }

    protected void put(String name, Object value) throws IOException {
        if (name == null) {
            throw new IllegalArgumentException("The name of the property cannot be null.");
        }
        if (name.length() == 0) {
            throw new IllegalArgumentException("The name of the property cannot be an emprty string.");
        }
        map.put(name, value);
    }
}
