/**
 * $Revision$
 * $Date$
 *
 * Copyright (C) 2006 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.wildfire.gateway.roster;

import java.io.Serializable;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.xmpp.packet.JID;

/**
 * Ignore the resource portion of the JID.
 * 
 * @author Noah Campbell
 *
 */
public final class NormalizedJID implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * The JID.
     *
     * @see JID
     */
    public final String JID;

    /**
     * The toStringValue.  Stored to increase efficiency.
     *
     * @see NormalizedJID
     */
    private final String toStringValue;

    /**
     * Construct a new <code>NormalizedJID</code>
     * @param jid
     */
    private NormalizedJID(JID jid) {
        JID = jid.toBareJID();
        toStringValue = JID + " (normalized)";
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof NormalizedJID) {
            NormalizedJID jid = (NormalizedJID)obj;
            return JID.equalsIgnoreCase(jid.JID);
        }
        else if (obj instanceof JID) {
            JID jid = new JID( ((JID)obj).toBareJID() );
            return JID.equalsIgnoreCase(jid.toBareJID());
        }
        else if (obj instanceof String) {
            JID jid = new JID((String)obj);
            jid = new JID(jid.toBareJID());
            return JID.equalsIgnoreCase(jid.toBareJID());
        }
        else {
            return super.equals(obj);
        }
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return JID.hashCode();
    }

    /**
     * Wrap a <code>JID</code> and return a <code>NormalizedJID</code>.  If the
     * <code>JID</code> has already been wrapped, then the cached version is returned.
     * 
     * @param jid
     * @return normalizedJID
     */
    public static NormalizedJID wrap(JID jid) {
        if (cache.containsKey(jid)) {
            return cache.get(jid);
        }
        else {
            NormalizedJID nJID = new NormalizedJID(jid);
            cache.put(jid, nJID);
            return nJID;
        }
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return toStringValue;
    }

    /**
     * The cache of <code>NormailzedJID</code>s.
     *
     * @see java.util.Map
     */
    private transient static final Map<JID, NormalizedJID> cache = new ConcurrentHashMap<JID, NormalizedJID>();

}
