/**
 * $RCSfile$
 * $Revision: 2779 $
 * $Date: 2005-09-05 17:00:45 -0300 (Mon, 05 Sep 2005) $
 *
 * Copyright 2003-2006 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.smackx.muc;

import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;

import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A <code>RoomListenerMultiplexor</code> multiplexes incoming packets on
 * a <code>Connection</code> using a single listener/filter pair.
 * A single <code>RoomListenerMultiplexor</code> is created for each
 * {@link org.jivesoftware.smack.Connection} that has joined MUC rooms
 * within its session.
 *
 * @author Larry Kirschner
 */
class RoomListenerMultiplexor implements ConnectionListener {

    // We use a WeakHashMap so that the GC can collect the monitor when the
    // connection is no longer referenced by any object.
    private static final Map<Connection, WeakReference<RoomListenerMultiplexor>> monitors =
            new WeakHashMap<Connection, WeakReference<RoomListenerMultiplexor>>();

    private Connection connection;
    private RoomMultiplexFilter filter;
    private RoomMultiplexListener listener;

    /**
     * Returns a new or existing RoomListenerMultiplexor for a given connection.
     *
     * @param conn the connection to monitor for room invitations.
     * @return a new or existing RoomListenerMultiplexor for a given connection.
     */
    public static RoomListenerMultiplexor getRoomMultiplexor(Connection conn) {
        synchronized (monitors) {
            if (!monitors.containsKey(conn) || monitors.get(conn).get() == null) {
                RoomListenerMultiplexor rm = new RoomListenerMultiplexor(conn, new RoomMultiplexFilter(),
                        new RoomMultiplexListener());

                rm.init();

                // We need to use a WeakReference because the monitor references the
                // connection and this could prevent the GC from collecting the monitor
                // when no other object references the monitor
                monitors.put(conn, new WeakReference<RoomListenerMultiplexor>(rm));
            }
            // Return the InvitationsMonitor that monitors the connection
            return monitors.get(conn).get();
        }
    }

    /**
     * All access should be through
     * the static method {@link #getRoomMultiplexor(Connection)}.
     */
    private RoomListenerMultiplexor(Connection connection, RoomMultiplexFilter filter,
            RoomMultiplexListener listener) {
        if (connection == null) {
            throw new IllegalArgumentException("Connection is null");
        }
        if (filter == null) {
            throw new IllegalArgumentException("Filter is null");
        }
        if (listener == null) {
            throw new IllegalArgumentException("Listener is null");
        }
        this.connection = connection;
        this.filter = filter;
        this.listener = listener;
    }

    public void addRoom(String address, PacketMultiplexListener roomListener) {
        filter.addRoom(address);
        listener.addRoom(address, roomListener);
    }

    public void connectionClosed() {
        cancel();
    }

    public void connectionClosedOnError(Exception e) {
        cancel();
    }

    public void reconnectingIn(int seconds) {
        // ignore
    }

    public void reconnectionSuccessful() {
        // ignore
    }

    public void reconnectionFailed(Exception e) {
        // ignore
    }

    /**
     * Initializes the listeners to detect received room invitations and to detect when the
     * connection gets closed. As soon as a room invitation is received the invitations
     * listeners will be fired. When the connection gets closed the monitor will remove
     * his listeners on the connection.
     */
    public void init() {
        connection.addConnectionListener(this);
        connection.addPacketListener(listener, filter);
    }

    public void removeRoom(String address) {
        filter.removeRoom(address);
        listener.removeRoom(address);
    }

    /**
     * Cancels all the listeners that this InvitationsMonitor has added to the connection.
     */
    private void cancel() {
        connection.removeConnectionListener(this);
        connection.removePacketListener(listener);
    }

    /**
     * The single <code>Connection</code>-level <code>PacketFilter</code> used by a {@link RoomListenerMultiplexor}
     * for all muc chat rooms on an <code>Connection</code>.
     * Each time a muc chat room is added to/removed from an
     * <code>Connection</code> the address for that chat room
     * is added to/removed from that <code>Connection</code>'s
     * <code>RoomMultiplexFilter</code>.
     */
    private static class RoomMultiplexFilter implements PacketFilter {

        private Map<String, String> roomAddressTable = new ConcurrentHashMap<String, String>();

        public boolean accept(Packet p) {
            String from = p.getFrom();
            if (from == null) {
                return false;
            }
            return roomAddressTable.containsKey(StringUtils.parseBareAddress(from).toLowerCase());
        }

        public void addRoom(String address) {
            if (address == null) {
                return;
            }
            roomAddressTable.put(address.toLowerCase(), address);
        }

        public void removeRoom(String address) {
            if (address == null) {
                return;
            }
            roomAddressTable.remove(address.toLowerCase());
        }
    }

    /**
     * The single <code>Connection</code>-level <code>PacketListener</code>
     * used by a {@link RoomListenerMultiplexor}
     * for all muc chat rooms on an <code>Connection</code>.
     * Each time a muc chat room is added to/removed from an
     * <code>Connection</code> the address and listener for that chat room
     * are added to/removed from that <code>Connection</code>'s
     * <code>RoomMultiplexListener</code>.
     *
     * @author Larry Kirschner
     */
    private static class RoomMultiplexListener implements PacketListener {

        private Map<String, PacketMultiplexListener> roomListenersByAddress =
                new ConcurrentHashMap<String, PacketMultiplexListener>();

        public void processPacket(Packet p) {
            String from = p.getFrom();
            if (from == null) {
                return;
            }

            PacketMultiplexListener listener =
                    roomListenersByAddress.get(StringUtils.parseBareAddress(from).toLowerCase());

            if (listener != null) {
                listener.processPacket(p);
            }
        }

        public void addRoom(String address, PacketMultiplexListener listener) {
            if (address == null) {
                return;
            }
            roomListenersByAddress.put(address.toLowerCase(), listener);
        }

        public void removeRoom(String address) {
            if (address == null) {
                return;
            }
            roomListenersByAddress.remove(address.toLowerCase());
        }
    }
}
