/**
 * Copyright 2012-2013 Florian Schmaus
 *
 * 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.ping;

import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.packet.DiscoverInfo;
import org.jivesoftware.smackx.ping.packet.Ping;
import org.jivesoftware.smackx.ping.packet.Pong;

/**
 * Implements the XMPP Ping as defined by XEP-0199. This protocol offers an
 * alternative to the traditional 'white space ping' approach of determining the
 * availability of an entity. The XMPP Ping protocol allows ping messages to be
 * send in a more XML-friendly approach, which can be used over more than one
 * hop in the communication path.
 * 
 * @author Florian Schmaus
 * @see <a href="http://www.xmpp.org/extensions/xep-0199.html">XEP-0199:XMPP
 *      Ping</a>
 */
public class PingManager {
    
    public static final String NAMESPACE = "urn:xmpp:ping";
    public static final String ELEMENT = "ping";
    

    private static Map<Connection, PingManager> instances =
            Collections.synchronizedMap(new WeakHashMap<Connection, PingManager>());
    
    static {
        Connection.addConnectionCreationListener(new ConnectionCreationListener() {
            public void connectionCreated(Connection connection) {
                new PingManager(connection);
            }
        });
    }
    
    private ScheduledExecutorService periodicPingExecutorService;
    private Connection connection;
    private int pingInterval = SmackConfiguration.getDefaultPingInterval();
    private Set<PingFailedListener> pingFailedListeners = Collections
            .synchronizedSet(new HashSet<PingFailedListener>());
    private ScheduledFuture<?> periodicPingTask;
    protected volatile long lastSuccessfulPingByTask = -1;

    
    // Ping Flood protection
    private long pingMinDelta = 100;
    private long lastPingStamp = 0; // timestamp of the last received ping
    
    // Timestamp of the last pong received, either from the server or another entity
    // Note, no need to synchronize this value, it will only increase over time
    private long lastSuccessfulManualPing = -1;
    
    private PingManager(Connection connection) {
        ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
        sdm.addFeature(NAMESPACE);
        this.connection = connection;
        init();
    }
    
    private void init() {
        periodicPingExecutorService = new ScheduledThreadPoolExecutor(1);
        PacketFilter pingPacketFilter = new PacketTypeFilter(Ping.class);
        connection.addPacketListener(new PacketListener() {
            /**
             * Sends a Pong for every Ping
             */
            public void processPacket(Packet packet) {
                if (pingMinDelta > 0) {
                    // Ping flood protection enabled
                    long currentMillies = System.currentTimeMillis();
                    long delta = currentMillies - lastPingStamp;
                    lastPingStamp = currentMillies;
                    if (delta < pingMinDelta) {
                        return;
                    }
                }
                Pong pong = new Pong((Ping)packet);
                connection.sendPacket(pong);
            }
        }
        , pingPacketFilter);
        connection.addConnectionListener(new ConnectionListener() {

            @Override
            public void connectionClosed() {
                maybeStopPingServerTask();
            }

            @Override
            public void connectionClosedOnError(Exception arg0) {
                maybeStopPingServerTask();
            }

            @Override
            public void reconnectionSuccessful() {
                maybeSchedulePingServerTask();
            }

            @Override
            public void reconnectingIn(int seconds) {
            }

            @Override
            public void reconnectionFailed(Exception e) {
            }
        });
        instances.put(connection, this);
        maybeSchedulePingServerTask();
    }

    public static PingManager getInstanceFor(Connection connection) {
        PingManager pingManager = instances.get(connection);
        
        if (pingManager == null) {
            pingManager = new PingManager(connection);
        }

        return pingManager;
    }

    public void setPingIntervall(int pingIntervall) {
        this.pingInterval = pingIntervall;
    }

    public int getPingIntervall() {
        return pingInterval;
    }
    
    public void registerPingFailedListener(PingFailedListener listener) {
        pingFailedListeners.add(listener);
    }
    
    public void unregisterPingFailedListener(PingFailedListener listener) {
        pingFailedListeners.remove(listener);
    }
    
    public void disablePingFloodProtection() {
        setPingMinimumInterval(-1);
    }
    
    public void setPingMinimumInterval(long ms) {
        this.pingMinDelta = ms;
    }
    
    public long getPingMinimumInterval() {
        return this.pingMinDelta;
    }
    
    /**
     * Pings the given jid and returns the IQ response which is either of 
     * IQ.Type.ERROR or IQ.Type.RESULT. If we are not connected or if there was
     * no reply, null is returned.
     * 
     * You should use isPingSupported(jid) to determine if XMPP Ping is 
     * supported by the user.
     * 
     * @param jid
     * @param pingTimeout
     * @return
     */
    public IQ ping(String jid, long pingTimeout) {
        // Make sure we actually connected to the server
        if (!connection.isAuthenticated())
            return null;
        
        Ping ping = new Ping(connection.getUser(), jid);
        
        PacketCollector collector =
                connection.createPacketCollector(new PacketIDFilter(ping.getPacketID()));
        
        connection.sendPacket(ping);
        
        IQ result = (IQ) collector.nextResult(pingTimeout);
        
        collector.cancel();
        return result;
    }
    
    /**
     * Pings the given jid and returns the IQ response with the default
     * packet reply timeout
     * 
     * @param jid
     * @return
     */
    public IQ ping(String jid) {
        return ping(jid, SmackConfiguration.getPacketReplyTimeout());
    }
    
    /**
     * Pings the given Entity.
     * 
     * Note that XEP-199 shows that if we receive a error response
     * service-unavailable there is no way to determine if the response was send
     * by the entity (e.g. a user JID) or from a server in between. This is
     * intended behavior to avoid presence leaks.
     * 
     * Always use isPingSupported(jid) to determine if XMPP Ping is supported
     * by the entity.
     * 
     * @param jid
     * @return True if a pong was received, otherwise false
     */
    public boolean pingEntity(String jid, long pingTimeout) {
        IQ result = ping(jid, pingTimeout);

        if (result == null || result.getType() == IQ.Type.ERROR) {
            return false;
        }
        pongReceived();
        return true;
    }
    
    public boolean pingEntity(String jid) {
        return pingEntity(jid, SmackConfiguration.getPacketReplyTimeout());
    }
    
    /**
     * Pings the user's server. Will notify the registered 
     * pingFailedListeners in case of error.
     * 
     * If we receive as response, we can be sure that it came from the server.
     * 
     * @return true if successful, otherwise false
     */
    public boolean pingMyServer(long pingTimeout) {
        IQ result = ping(connection.getServiceName(), pingTimeout);

        if (result == null) {
            for (PingFailedListener l : pingFailedListeners) {
                l.pingFailed();
            }
            return false;
        }
        // Maybe not really a pong, but an answer is an answer
        pongReceived();
        return true;
    }
    
    /**
     * Pings the user's server with the PacketReplyTimeout as defined
     * in SmackConfiguration.
     * 
     * @return true if successful, otherwise false
     */
    public boolean pingMyServer() {
        return pingMyServer(SmackConfiguration.getPacketReplyTimeout());
    }
    
    /**
     * Returns true if XMPP Ping is supported by a given JID
     * 
     * @param jid
     * @return
     */
    public boolean isPingSupported(String jid) {
        try {
            DiscoverInfo result =
                ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(jid);
            return result.containsFeature(NAMESPACE);
        }
        catch (XMPPException e) {
            return false;
        }
    }
    
    /**
     * Returns the time of the last successful Ping Pong with the 
     * users server. If there was no successful Ping (e.g. because this
     * feature is disabled) -1 will be returned.
     *  
     * @return
     */
    public long getLastSuccessfulPing() {
        return Math.max(lastSuccessfulPingByTask, lastSuccessfulManualPing);
    }
    
    protected Set<PingFailedListener> getPingFailedListeners() {
        return pingFailedListeners;
    }

    /**
     * Cancels any existing periodic ping task if there is one and schedules a new ping task if pingInterval is greater
     * then zero.
     * 
     */
    protected synchronized void maybeSchedulePingServerTask() {
        maybeStopPingServerTask();
        if (pingInterval > 0) {
            periodicPingTask = periodicPingExecutorService.schedule(new ServerPingTask(connection), pingInterval,
                    TimeUnit.SECONDS);
        }
    }

    private void maybeStopPingServerTask() {
        if (periodicPingTask != null) {
            periodicPingTask.cancel(true);
            periodicPingTask = null;
        }
    }

    private void pongReceived() {
        lastSuccessfulManualPing = System.currentTimeMillis();
    }
}
