/*
 * Copyright 2013 gitblit.com.
 *
 * 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 com.gitblit.fanout;

import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Base class for Fanout service implementations.
 * 
 * Subclass implementations can be used as a Sparkleshare PubSub notification
 * server.  This allows Sparkleshare to be used in conjunction with Gitblit
 * behind a corporate firewall that restricts or prohibits client internet access
 * to the default Sparkleshare PubSub server: notifications.sparkleshare.org
 * 
 * @author James Moger
 *
 */
public abstract class FanoutService implements Runnable {

	private final static Logger logger = LoggerFactory.getLogger(FanoutService.class);
	
	public final static int DEFAULT_PORT = 17000;
	
	protected final static int serviceTimeout = 5000;

	protected final String host;
	protected final int port;
	protected final String name; 
	
	private Thread serviceThread;
	
	private final Map<String, FanoutServiceConnection> connections;
	private final Map<String, Set<FanoutServiceConnection>> subscriptions;

	protected final AtomicBoolean isRunning;
	private final AtomicBoolean strictRequestTermination;
	private final AtomicBoolean allowAllChannelAnnouncements;
	private final AtomicInteger concurrentConnectionLimit;
	
	private final Date bootDate;
	private final AtomicLong rejectedConnectionCount;
	private final AtomicInteger peakConnectionCount;
	private final AtomicLong totalConnections;
	private final AtomicLong totalAnnouncements;
	private final AtomicLong totalMessages;
	private final AtomicLong totalSubscribes;
	private final AtomicLong totalUnsubscribes;
	private final AtomicLong totalPings;

	protected FanoutService(String host, int port, String name) {
		this.host = host;
		this.port = port;
		this.name = name;
		
		connections = new ConcurrentHashMap<String, FanoutServiceConnection>();
		subscriptions = new ConcurrentHashMap<String, Set<FanoutServiceConnection>>();
		subscriptions.put(FanoutConstants.CH_ALL, new ConcurrentSkipListSet<FanoutServiceConnection>());
		
		isRunning = new AtomicBoolean(false);
		strictRequestTermination = new AtomicBoolean(false);
		allowAllChannelAnnouncements = new AtomicBoolean(false);
		concurrentConnectionLimit = new AtomicInteger(0);
		
		bootDate = new Date();
		rejectedConnectionCount = new AtomicLong(0);
		peakConnectionCount = new AtomicInteger(0);
		totalConnections = new AtomicLong(0);
		totalAnnouncements = new AtomicLong(0);
		totalMessages = new AtomicLong(0);
		totalSubscribes = new AtomicLong(0);
		totalUnsubscribes = new AtomicLong(0);
		totalPings = new AtomicLong(0);
	}

	/*
	 * Abstract methods
	 */
	
	protected abstract boolean isConnected();
	
	protected abstract boolean connect();
	
	protected abstract void listen() throws IOException;
	
	protected abstract void disconnect();
	
	/**
	 * Returns true if the service requires \n request termination.
	 * 
	 * @return true if request requires \n termination
	 */
	public boolean isStrictRequestTermination() {
		return strictRequestTermination.get();
	}

	/**
	 * Control the termination of fanout requests. If true, fanout requests must
	 * be terminated with \n. If false, fanout requests may be terminated with
	 * \n, \r, \r\n, or \n\r. This is useful for debugging with a telnet client.
	 * 
	 * @param isStrictTermination
	 */
	public void setStrictRequestTermination(boolean isStrictTermination) {
		strictRequestTermination.set(isStrictTermination);
	}
	
	/**
	 * Returns the maximum allowable concurrent fanout connections.
	 *  
	 * @return the maximum allowable concurrent connection count
	 */
	public int getConcurrentConnectionLimit() {
		return concurrentConnectionLimit.get();
	}
	
	/**
	 * Sets the maximum allowable concurrent fanout connection count.
	 * 
	 * @param value
	 */
	public void setConcurrentConnectionLimit(int value) {
		concurrentConnectionLimit.set(value);
	}
	
	/**
	 * Returns true if connections are allowed to announce on the all channel.
	 *  
	 * @return true if connections are allowed to announce on the all channel
	 */
	public boolean allowAllChannelAnnouncements() {
		return allowAllChannelAnnouncements.get();
	}
	
	/**
	 * Allows/prohibits connections from announcing on the ALL channel.
	 * 
	 * @param value
	 */
	public void setAllowAllChannelAnnouncements(boolean value) {
		allowAllChannelAnnouncements.set(value);
	}
	
	/**
	 * Returns the current connections
	 * 
	 * @param channel
	 * @return map of current connections keyed by their id
	 */
	public Map<String, FanoutServiceConnection> getCurrentConnections() {
		return connections;
	}
	
	/**
	 * Returns all subscriptions
	 * 
	 * @return map of current subscriptions keyed by channel name
	 */
	public Map<String, Set<FanoutServiceConnection>> getCurrentSubscriptions() {
		return subscriptions;
	}

	/**
	 * Returns the subscriptions for the specified channel
	 * 
	 * @param channel
	 * @return set of subscribed connections for the specified channel
	 */
	public Set<FanoutServiceConnection> getCurrentSubscriptions(String channel) {
		return subscriptions.get(channel);
	}

	/**
	 * Returns the runtime statistics object for this service.
	 * 
	 * @return stats
	 */
	public FanoutStats getStatistics() {
		FanoutStats stats = new FanoutStats();
		
		// settings
		stats.allowAllChannelAnnouncements = allowAllChannelAnnouncements();
		stats.concurrentConnectionLimit = getConcurrentConnectionLimit();
		stats.strictRequestTermination = isStrictRequestTermination();
		
		// runtime stats
		stats.bootDate = bootDate;
		stats.rejectedConnectionCount = rejectedConnectionCount.get();
		stats.peakConnectionCount = peakConnectionCount.get();
		stats.totalConnections = totalConnections.get();
		stats.totalAnnouncements = totalAnnouncements.get();
		stats.totalMessages = totalMessages.get();
		stats.totalSubscribes = totalSubscribes.get();
		stats.totalUnsubscribes = totalUnsubscribes.get();
		stats.totalPings = totalPings.get();		
		stats.currentConnections = connections.size();
		stats.currentChannels = subscriptions.size();
		stats.currentSubscriptions = subscriptions.size() * connections.size();
		return stats;
	}
	
	/**
	 * Returns true if the service is ready.
	 * 
	 * @return true, if the service is ready
	 */
	public boolean isReady() {
		if (isRunning.get()) {
			return isConnected();
		}
		return false;
	}

	/**
	 * Start the Fanout service thread and immediatel return.
	 * 
	 */
	public void start() {
		if (isRunning.get()) {
			logger.warn(MessageFormat.format("{0} is already running", name));
			return;
		}
		serviceThread = new Thread(this);
		serviceThread.setName(MessageFormat.format("{0} {1}:{2,number,0}", name, host == null ? "all" : host, port));
		serviceThread.start();
	}
	
	/**
	 * Start the Fanout service thread and wait until it is accepting connections.
	 * 
	 */
	public void startSynchronously() {
		start();
		while (!isReady()) {
			try {
				Thread.sleep(100);
			} catch (Exception e) {
			}
		}
	}
		
	/**
	 * Stop the Fanout service.  This method returns when the service has been
	 * completely shutdown.
	 */
	public void stop() {
		if (!isRunning.get()) {
			logger.warn(MessageFormat.format("{0} is not running", name));
			return;
		}
		logger.info(MessageFormat.format("stopping {0}...", name));
		isRunning.set(false);
		try {
			if (serviceThread != null) {
				serviceThread.join();
				serviceThread = null;
			}
		} catch (InterruptedException e1) {
			logger.error("", e1);
		}
		logger.info(MessageFormat.format("stopped {0}", name));
	}
	
	/**
	 * Main execution method of the service
	 */
	@Override
	public final void run() {
		disconnect();
		resetState();
		isRunning.set(true);
		while (isRunning.get()) {
			if (connect()) {
				try {
					listen();
				} catch (IOException e) {
					logger.error(MessageFormat.format("error processing {0}", name), e);
					isRunning.set(false);
				}
			} else {
				try {
					Thread.sleep(serviceTimeout);
				} catch (InterruptedException x) {
				}
			}
		}
		disconnect();		
		resetState();
	}
	
	protected void resetState() {
		// reset state data
		connections.clear();
		subscriptions.clear();
		rejectedConnectionCount.set(0);
		peakConnectionCount.set(0);
		totalConnections.set(0);
		totalAnnouncements.set(0);
		totalMessages.set(0);
		totalSubscribes.set(0);
		totalUnsubscribes.set(0);
		totalPings.set(0);
	}

	/**
	 * Configure the client connection socket.
	 * 
	 * @param socket
	 * @throws SocketException
	 */
	protected void configureClientSocket(Socket socket) throws SocketException {
		socket.setKeepAlive(true);				
		socket.setSoLinger(true, 0); // immediately discard any remaining data
	}
	
	/**
	 * Add the connection to the connections map.
	 * 
	 * @param connection
	 * @return false if the connection was rejected due to too many concurrent
	 *         connections
	 */
	protected boolean addConnection(FanoutServiceConnection connection) {		
		int limit = getConcurrentConnectionLimit();
		if (limit > 0 && connections.size() > limit) {
			logger.info(MessageFormat.format("hit {0,number,0} connection limit, rejecting fanout connection", concurrentConnectionLimit));
			increment(rejectedConnectionCount);
			connection.busy();
			return false;
		}
		
		// add the connection to our map
		connections.put(connection.id, connection);

		// track peak number of concurrent connections
		if (connections.size() > peakConnectionCount.get()) {
			peakConnectionCount.set(connections.size());
		}

		logger.info("fanout new connection " + connection.id);
		connection.connected();
		return true;
	}
	
	/**
	 * Remove the connection from the connections list and from subscriptions.
	 * 
	 * @param connection
	 */
	protected void removeConnection(FanoutServiceConnection connection) {
		connections.remove(connection.id);
		Iterator<Map.Entry<String, Set<FanoutServiceConnection>>> itr = subscriptions.entrySet().iterator();
		while (itr.hasNext()) {
			Map.Entry<String, Set<FanoutServiceConnection>> entry = itr.next();
			Set<FanoutServiceConnection> subscriptions = entry.getValue();
			subscriptions.remove(connection);
			if (!FanoutConstants.CH_ALL.equals(entry.getKey())) {
				if (subscriptions.size() == 0) {
					itr.remove();
					logger.info(MessageFormat.format("fanout remove channel {0}, no subscribers", entry.getKey()));
				}
			}
		}
		logger.info(MessageFormat.format("fanout connection {0} removed", connection.id));
	}
	
	/**
	 * Tests to see if the connection is being monitored by the service.
	 * 
	 * @param connection
	 * @return true if the service is monitoring the connection
	 */
	protected boolean hasConnection(FanoutServiceConnection connection) {
		return connections.containsKey(connection.id);
	}
	
	/**
	 * Reply to a connection on the specified channel.
	 * 
	 * @param connection
	 * @param channel
	 * @param message
	 * @return the reply
	 */
	protected String reply(FanoutServiceConnection connection, String channel, String message) {		
		if (channel != null && channel.length() > 0) {
			increment(totalMessages);
		}
		return connection.reply(channel, message);
	}
	
	/**
	 * Service method to broadcast a message to all connections.
	 * 
	 * @param message
	 */
	public void broadcastAll(String message) {
		broadcast(connections.values(), FanoutConstants.CH_ALL, message);
		increment(totalAnnouncements);
	}
	
	/**
	 * Service method to broadcast a message to connections subscribed to the
	 * channel.
	 * 
	 * @param message
	 */
	public void broadcast(String channel, String message) {
		List<FanoutServiceConnection> connections = new ArrayList<FanoutServiceConnection>(subscriptions.get(channel));
		broadcast(connections, channel, message);
		increment(totalAnnouncements);
	}
	
	/**
	 * Broadcast a message to connections subscribed to the specified channel.
	 * 
	 * @param connections
	 * @param channel
	 * @param message
	 */
	protected void broadcast(Collection<FanoutServiceConnection> connections, String channel, String message) {
		for (FanoutServiceConnection connection : connections) {
			reply(connection, channel, message);
		}
	}
	
	/**
	 * Process an incoming Fanout request.
	 * 
	 * @param connection
	 * @param req
	 * @return the reply to the request, may be null
	 */
	protected String processRequest(FanoutServiceConnection connection, String req) {
		logger.info(MessageFormat.format("fanout request from {0}: {1}", connection.id, req));
		String[] fields = req.split(" ", 3);
		String action = fields[0];
		String channel = fields.length >= 2 ? fields[1] : null;
		String message = fields.length >= 3 ? fields[2] : null;
		try {
			return processRequest(connection, action, channel, message);
		} catch (IllegalArgumentException e) {
			// invalid action
			logger.error(MessageFormat.format("fanout connection {0} requested invalid action {1}", connection.id, action));
			logger.error(asHexArray(req));
		}
		return null;
	}
	
	/**
	 * Process the Fanout request.
	 * 
	 * @param connection
	 * @param action
	 * @param channel
	 * @param message
	 * @return the reply to the request, may be null
	 * @throws IllegalArgumentException
	 */
	protected String processRequest(FanoutServiceConnection connection, String action, String channel, String message) throws IllegalArgumentException {
		if ("ping".equals(action)) {
			// ping
			increment(totalPings);
			return reply(connection, null, "" + System.currentTimeMillis());
		} else if ("info".equals(action)) {
			// info
			String info = getStatistics().info();
			return reply(connection, null, info);
		} else if ("announce".equals(action)) {
			// announcement
			if (!allowAllChannelAnnouncements.get() && FanoutConstants.CH_ALL.equals(channel)) {
				// prohibiting connection-sourced all announcements
				logger.warn(MessageFormat.format("fanout connection {0} attempted to announce {1} on ALL channel", connection.id, message));
			} else if ("debug".equals(channel)) {
				// prohibiting connection-sourced debug announcements
				logger.warn(MessageFormat.format("fanout connection {0} attempted to announce {1} on DEBUG channel", connection.id, message));
			} else {
				// acceptable announcement
				List<FanoutServiceConnection> connections = new ArrayList<FanoutServiceConnection>(subscriptions.get(channel));
				connections.remove(connection); // remove announcer
				broadcast(connections, channel, message);
				increment(totalAnnouncements);
			}
		} else if ("subscribe".equals(action)) {
			// subscribe
			if (!subscriptions.containsKey(channel)) {
				logger.info(MessageFormat.format("fanout new channel {0}", channel));
				subscriptions.put(channel, new ConcurrentSkipListSet<FanoutServiceConnection>());
			}
			subscriptions.get(channel).add(connection);
			logger.debug(MessageFormat.format("fanout connection {0} subscribed to channel {1}", connection.id, channel));
			increment(totalSubscribes);
		} else if ("unsubscribe".equals(action)) {
			// unsubscribe
			if (subscriptions.containsKey(channel)) {
				subscriptions.get(channel).remove(connection);
				if (subscriptions.get(channel).size() == 0) {
					subscriptions.remove(channel);
				}
				increment(totalUnsubscribes);
			}
		} else {
			// invalid action
			throw new IllegalArgumentException(action);
		}
		return null;
	}
	
	private String asHexArray(String req) {
		StringBuilder sb = new StringBuilder();
		for (char c : req.toCharArray()) {
			sb.append(Integer.toHexString(c)).append(' ');
		}
		return "[ " + sb.toString().trim() + " ]";
	}
	
	/**
	 * Increment a long and prevent negative rollover.
	 * 
	 * @param counter
	 */
	private void increment(AtomicLong counter) {
		long v = counter.incrementAndGet();
		if (v < 0) {
			counter.set(0);
		}
	}
	
	@Override
	public String toString() {
		return name;
	}
}