/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
 * Copyright 2003-2007 Jive Software.
 *
 * All rights reserved. Licensed 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.jivesoftware.smack.packet;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.CopyOnWriteArrayList;

import org.jivesoftware.smack.util.StringUtils;

/**
 * Base class for XMPP packets. Every packet has a unique ID (which is automatically
 * generated, but can be overriden). Optionally, the "to" and "from" fields can be set,
 * as well as an arbitrary number of properties.
 *
 * Properties provide an easy mechanism for clients to share data. Each property has a
 * String name, and a value that is a Java primitive (int, long, float, double, boolean)
 * or any Serializable object (a Java object is Serializable when it implements the
 * Serializable interface).
 *
 * @author Matt Tucker
 */
public abstract class Packet {

    protected static final String DEFAULT_LANGUAGE =
            java.util.Locale.getDefault().getLanguage().toLowerCase();

    private static String DEFAULT_XML_NS = null;

    /**
     * Constant used as packetID to indicate that a packet has no id. To indicate that a packet
     * has no id set this constant as the packet's id. When the packet is asked for its id the
     * answer will be <tt>null</tt>.
     */
    public static final String ID_NOT_AVAILABLE = "ID_NOT_AVAILABLE";
    
    /**
     * Date format as defined in XEP-0082 - XMPP Date and Time Profiles.
     * The time zone is set to UTC.
     * <p>
     * Date formats are not synchronized. Since multiple threads access the format concurrently,
     * it must be synchronized externally. 
     */
    public static final DateFormat XEP_0082_UTC_FORMAT = new SimpleDateFormat(
                    "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    static {
        XEP_0082_UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
    }


    /**
     * A prefix helps to make sure that ID's are unique across mutliple instances.
     */
    private static String prefix = StringUtils.randomString(5) + "-";

    /**
     * Keeps track of the current increment, which is appended to the prefix to
     * forum a unique ID.
     */
    private static long id = 0;

    private String xmlns = DEFAULT_XML_NS;

    /**
     * Returns the next unique id. Each id made up of a short alphanumeric
     * prefix along with a unique numeric value.
     *
     * @return the next id.
     */
    public static synchronized String nextID() {
        return prefix + Long.toString(id++);
    }

    public static void setDefaultXmlns(String defaultXmlns) {
        DEFAULT_XML_NS = defaultXmlns;
    }

    private String packetID = null;
    private String to = null;
    private String from = null;
    private final List<PacketExtension> packetExtensions
            = new CopyOnWriteArrayList<PacketExtension>();

    private final Map<String,Object> properties = new HashMap<String, Object>();
    private XMPPError error = null;

    public Packet() {
    }

    public Packet(Packet p) {
        packetID = p.getPacketID();
        to = p.getTo();
        from = p.getFrom();
        xmlns = p.xmlns;
        error = p.error;

        // Copy extensions
        for (PacketExtension pe : p.getExtensions()) {
            addExtension(pe);
        }
    }

    /**
     * Returns the unique ID of the packet. The returned value could be <tt>null</tt> when
     * ID_NOT_AVAILABLE was set as the packet's id.
     *
     * @return the packet's unique ID or <tt>null</tt> if the packet's id is not available.
     */
    public String getPacketID() {
        if (ID_NOT_AVAILABLE.equals(packetID)) {
            return null;
        }

        if (packetID == null) {
            packetID = nextID();
        }
        return packetID;
    }

    /**
     * Sets the unique ID of the packet. To indicate that a packet has no id
     * pass the constant ID_NOT_AVAILABLE as the packet's id value.
     *
     * @param packetID the unique ID for the packet.
     */
    public void setPacketID(String packetID) {
        this.packetID = packetID;
    }

    /**
     * Returns who the packet is being sent "to", or <tt>null</tt> if
     * the value is not set. The XMPP protocol often makes the "to"
     * attribute optional, so it does not always need to be set.<p>
     *
     * The StringUtils class provides several useful methods for dealing with
     * XMPP addresses such as parsing the
     * {@link StringUtils#parseBareAddress(String) bare address},
     * {@link StringUtils#parseName(String) user name},
     * {@link StringUtils#parseServer(String) server}, and
     * {@link StringUtils#parseResource(String) resource}.  
     *
     * @return who the packet is being sent to, or <tt>null</tt> if the
     *      value has not been set.
     */
    public String getTo() {
        return to;
    }

    /**
     * Sets who the packet is being sent "to". The XMPP protocol often makes
     * the "to" attribute optional, so it does not always need to be set.
     *
     * @param to who the packet is being sent to.
     */
    public void setTo(String to) {
        this.to = to;
    }

    /**
     * Returns who the packet is being sent "from" or <tt>null</tt> if
     * the value is not set. The XMPP protocol often makes the "from"
     * attribute optional, so it does not always need to be set.<p>
     *
     * The StringUtils class provides several useful methods for dealing with
     * XMPP addresses such as parsing the
     * {@link StringUtils#parseBareAddress(String) bare address},
     * {@link StringUtils#parseName(String) user name},
     * {@link StringUtils#parseServer(String) server}, and
     * {@link StringUtils#parseResource(String) resource}.  
     *
     * @return who the packet is being sent from, or <tt>null</tt> if the
     *      value has not been set.
     */
    public String getFrom() {
        return from;
    }

    /**
     * Sets who the packet is being sent "from". The XMPP protocol often
     * makes the "from" attribute optional, so it does not always need to
     * be set.
     *
     * @param from who the packet is being sent to.
     */
    public void setFrom(String from) {
        this.from = from;
    }

    /**
     * Returns the error associated with this packet, or <tt>null</tt> if there are
     * no errors.
     *
     * @return the error sub-packet or <tt>null</tt> if there isn't an error.
     */
    public XMPPError getError() {
        return error;
    }

    /**
     * Sets the error for this packet.
     *
     * @param error the error to associate with this packet.
     */
    public void setError(XMPPError error) {
        this.error = error;
    }

    /**
     * Returns an unmodifiable collection of the packet extensions attached to the packet.
     *
     * @return the packet extensions.
     */
    public synchronized Collection<PacketExtension> getExtensions() {
        if (packetExtensions == null) {
            return Collections.emptyList();
        }
        return Collections.unmodifiableList(new ArrayList<PacketExtension>(packetExtensions));
    }

    /**
     * Returns the first extension of this packet that has the given namespace.
     *
     * @param namespace the namespace of the extension that is desired.
     * @return the packet extension with the given namespace.
     */
    public PacketExtension getExtension(String namespace) {
        return getExtension(null, namespace);
    }

    /**
     * Returns the first packet extension that matches the specified element name and
     * namespace, or <tt>null</tt> if it doesn't exist. If the provided elementName is null
     * than only the provided namespace is attempted to be matched. Packet extensions are
     * are arbitrary XML sub-documents in standard XMPP packets. By default, a 
     * DefaultPacketExtension instance will be returned for each extension. However, 
     * PacketExtensionProvider instances can be registered with the 
     * {@link org.jivesoftware.smack.provider.ProviderManager ProviderManager}
     * class to handle custom parsing. In that case, the type of the Object
     * will be determined by the provider.
     *
     * @param elementName the XML element name of the packet extension. (May be null)
     * @param namespace the XML element namespace of the packet extension.
     * @return the extension, or <tt>null</tt> if it doesn't exist.
     */
    public PacketExtension getExtension(String elementName, String namespace) {
        if (namespace == null) {
            return null;
        }
        for (PacketExtension ext : packetExtensions) {
            if ((elementName == null || elementName.equals(ext.getElementName()))
                    && namespace.equals(ext.getNamespace()))
            {
                return ext;
            }
        }
        return null;
    }

    /**
     * Adds a packet extension to the packet. Does nothing if extension is null.
     *
     * @param extension a packet extension.
     */
    public void addExtension(PacketExtension extension) {
        if (extension == null) return;
        packetExtensions.add(extension);
    }

    /**
     * Adds a collection of packet extensions to the packet. Does nothing if extensions is null.
     * 
     * @param extensions a collection of packet extensions
     */
    public void addExtensions(Collection<PacketExtension> extensions) {
        if (extensions == null) return;
        packetExtensions.addAll(extensions);
    }

    /**
     * Removes a packet extension from the packet.
     *
     * @param extension the packet extension to remove.
     */
    public void removeExtension(PacketExtension extension)  {
        packetExtensions.remove(extension);
    }

    /**
     * Returns the packet property with the specified name or <tt>null</tt> if the
     * property doesn't exist. Property values that were originally primitives will
     * be returned as their object equivalent. For example, an int property will be
     * returned as an Integer, a double as a Double, etc.
     *
     * @param name the name of the property.
     * @return the property, or <tt>null</tt> if the property doesn't exist.
     */
    public synchronized Object getProperty(String name) {
        if (properties == null) {
            return null;
        }
        return properties.get(name);
    }

    /**
     * Sets a property with an Object as the value. The value must be Serializable
     * or an IllegalArgumentException will be thrown.
     *
     * @param name the name of the property.
     * @param value the value of the property.
     */
    public synchronized void setProperty(String name, Object value) {
        if (!(value instanceof Serializable)) {
            throw new IllegalArgumentException("Value must be serialiazble");
        }
        properties.put(name, value);
    }

    /**
     * Deletes a property.
     *
     * @param name the name of the property to delete.
     */
    public synchronized void deleteProperty(String name) {
        if (properties == null) {
            return;
        }
        properties.remove(name);
    }

    /**
     * Returns an unmodifiable collection of all the property names that are set.
     *
     * @return all property names.
     */
    public synchronized Collection<String> getPropertyNames() {
        if (properties == null) {
            return Collections.emptySet();
        }
        return Collections.unmodifiableSet(new HashSet<String>(properties.keySet()));
    }

    /**
     * Returns the packet as XML. Every concrete extension of Packet must implement
     * this method. In addition to writing out packet-specific data, every sub-class
     * should also write out the error and the extensions data if they are defined.
     *
     * @return the XML format of the packet as a String.
     */
    public abstract String toXML();

    /**
     * Returns the extension sub-packets (including properties data) as an XML
     * String, or the Empty String if there are no packet extensions.
     *
     * @return the extension sub-packets as XML or the Empty String if there
     * are no packet extensions.
     */
    protected synchronized String getExtensionsXML() {
        StringBuilder buf = new StringBuilder();
        // Add in all standard extension sub-packets.
        for (PacketExtension extension : getExtensions()) {
            buf.append(extension.toXML());
        }
        // Add in packet properties.
        if (properties != null && !properties.isEmpty()) {
            buf.append("<properties xmlns=\"http://www.jivesoftware.com/xmlns/xmpp/properties\">");
            // Loop through all properties and write them out.
            for (String name : getPropertyNames()) {
                Object value = getProperty(name);
                buf.append("<property>");
                buf.append("<name>").append(StringUtils.escapeForXML(name)).append("</name>");
                buf.append("<value type=\"");
                if (value instanceof Integer) {
                    buf.append("integer\">").append(value).append("</value>");
                }
                else if (value instanceof Long) {
                    buf.append("long\">").append(value).append("</value>");
                }
                else if (value instanceof Float) {
                    buf.append("float\">").append(value).append("</value>");
                }
                else if (value instanceof Double) {
                    buf.append("double\">").append(value).append("</value>");
                }
                else if (value instanceof Boolean) {
                    buf.append("boolean\">").append(value).append("</value>");
                }
                else if (value instanceof String) {
                    buf.append("string\">");
                    buf.append(StringUtils.escapeForXML((String)value));
                    buf.append("</value>");
                }
                // Otherwise, it's a generic Serializable object. Serialized objects are in
                // a binary format, which won't work well inside of XML. Therefore, we base-64
                // encode the binary data before adding it.
                else {
                    ByteArrayOutputStream byteStream = null;
                    ObjectOutputStream out = null;
                    try {
                        byteStream = new ByteArrayOutputStream();
                        out = new ObjectOutputStream(byteStream);
                        out.writeObject(value);
                        buf.append("java-object\">");
                        String encodedVal = StringUtils.encodeBase64(byteStream.toByteArray());
                        buf.append(encodedVal).append("</value>");
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                    finally {
                        if (out != null) {
                            try {
                                out.close();
                            }
                            catch (Exception e) {
                                // Ignore.
                            }
                        }
                        if (byteStream != null) {
                            try {
                                byteStream.close();
                            }
                            catch (Exception e) {
                                // Ignore.
                            }
                        }
                    }
                }
                buf.append("</property>");
            }
            buf.append("</properties>");
        }
        return buf.toString();
    }

    public String getXmlns() {
        return this.xmlns;
    }

    /**
     * Returns the default language used for all messages containing localized content.
     * 
     * @return the default language
     */
    public static String getDefaultLanguage() {
        return DEFAULT_LANGUAGE;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Packet packet = (Packet) o;

        if (error != null ? !error.equals(packet.error) : packet.error != null) { return false; }
        if (from != null ? !from.equals(packet.from) : packet.from != null) { return false; }
        if (!packetExtensions.equals(packet.packetExtensions)) { return false; }
        if (packetID != null ? !packetID.equals(packet.packetID) : packet.packetID != null) {
            return false;
        }
        if (properties != null ? !properties.equals(packet.properties)
                : packet.properties != null) {
            return false;
        }
        if (to != null ? !to.equals(packet.to) : packet.to != null)  { return false; }
        return !(xmlns != null ? !xmlns.equals(packet.xmlns) : packet.xmlns != null);
    }

    public int hashCode() {
        int result;
        result = (xmlns != null ? xmlns.hashCode() : 0);
        result = 31 * result + (packetID != null ? packetID.hashCode() : 0);
        result = 31 * result + (to != null ? to.hashCode() : 0);
        result = 31 * result + (from != null ? from.hashCode() : 0);
        result = 31 * result + packetExtensions.hashCode();
        result = 31 * result + properties.hashCode();
        result = 31 * result + (error != null ? error.hashCode() : 0);
        return result;
    }
}
