/**********************************************************************
 * Copyright (c) 2003, 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *    IBM Corporation - Initial API and implementation
 *     Tianchao Li (Tianchao.Li@gmail.com) - Start monitors by default 
 **********************************************************************/
package org.eclipse.wst.internet.monitor.core.internal;

import java.io.ByteArrayInputStream;
import java.util.*;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.internet.monitor.core.internal.http.ResendHTTPRequest;
import org.eclipse.wst.internet.monitor.core.internal.provisional.*;
/**
 * 
 */
public class MonitorManager {
	private static final int ADD = 0;
	private static final int CHANGE = 1;
	private static final int REMOVE = 2;

	// monitors
	protected List<IMonitor> monitors;
	protected Map<IMonitor, AcceptThread> threads = new HashMap<IMonitor, AcceptThread>();
	
	protected List<IMonitorListener> monitorListeners = new ArrayList<IMonitorListener>();

	private Preferences.IPropertyChangeListener pcl;
	protected boolean ignorePreferenceChanges = false;
	
	protected Map<Request, List<ResendHTTPRequest>> resendMap = new HashMap<Request, List<ResendHTTPRequest>>();
	
	protected static MonitorManager instance;
	
	static {
		MonitorPlugin.getInstance().executeStartups();
	}
	
	/**
	 * Return a static instance.
	 * 
	 * @return the instance
	 */
	public static MonitorManager getInstance() {
		if (instance == null) {
			instance = new MonitorManager();
			instance.startMonitors();
		}
		
		return instance;
	}
	
	private MonitorManager() {
		loadMonitors();
		
		pcl = new Preferences.IPropertyChangeListener() {
			public void propertyChange(Preferences.PropertyChangeEvent event) {
				if (ignorePreferenceChanges)
					return;
				String property = event.getProperty();
				if (property.equals("monitors")) {
					loadMonitors();
				}
			}
		};
		
		MonitorPlugin.getInstance().getPluginPreferences().addPropertyChangeListener(pcl);
	}
	
	protected void dispose() {
		MonitorPlugin.getInstance().getPluginPreferences().removePropertyChangeListener(pcl);
	}
	
	/**
	 * Create a new monitor.
	 * 
	 * @return the new monitor
	 */
	public IMonitorWorkingCopy createMonitor() {
		return new MonitorWorkingCopy();
	}
	
	/**
	 * Return the list of monitors.
	 * 
	 * @return the list of monitors
	 */
	public List<IMonitor> getMonitors() {
		return new ArrayList<IMonitor>(monitors);
	}

	protected synchronized void addMonitor(IMonitor monitor) {
		if (!monitors.contains(monitor))
			monitors.add(monitor);
		fireMonitorEvent(monitor, ADD);
		saveMonitors();
	}
	
	protected boolean isRunning(IMonitor monitor) {
		return (threads.get(monitor) != null);
	}

	/**
	 * Start a monitor.
	 * 
	 * @param monitor the monitor
	 * @throws CoreException
	 */
	public void startMonitor(IMonitor monitor) throws CoreException {
		if (!monitors.contains(monitor))
			return;
		
		if (AcceptThread.isPortInUse(monitor.getLocalPort()))
			throw new CoreException(new Status(IStatus.ERROR, MonitorPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorPortInUse, monitor.getLocalPort() + ""), null));
		
		AcceptThread thread = new AcceptThread(monitor);
		thread.startServer();
		threads.put(monitor, thread);
	}
	
	/**
	 * Stop a monitor.
	 * 
	 * @param monitor the monitor
	 */
	public void stopMonitor(IMonitor monitor) {
		if (!monitors.contains(monitor))
			return;
		
		AcceptThread thread = threads.get(monitor);
		if (thread != null) {
			thread.stopServer();
			threads.remove(monitor);
		}
	}
	
	protected synchronized void removeMonitor(IMonitor monitor) {
		if (monitor.isRunning())
			stopMonitor(monitor);
		monitors.remove(monitor);
		fireMonitorEvent(monitor, REMOVE);
		saveMonitors();
	}
	
	protected synchronized void monitorChanged(IMonitor monitor) {
		fireMonitorEvent(monitor, CHANGE);
		saveMonitors();
	}
	
	protected boolean exists(IMonitor monitor) {
		return (monitors.contains(monitor));
	}
	
	/**
	 * Add monitor listener.
	 * 
	 * @param listener
	 */
	public synchronized void addMonitorListener(IMonitorListener listener) {
		if (!monitorListeners.contains(listener))
			monitorListeners.add(listener);
	}

	/**
	 * Remove monitor listener.
	 * 
	 * @param listener
	 */
	public synchronized void removeMonitorListener(IMonitorListener listener) {
		if (monitorListeners.contains(listener))
			monitorListeners.remove(listener);
	}
	
	/**
	 * Fire a monitor event.
	 * 
	 * @param monitor the monitor
	 * @param type the type of event
	 */
	protected void fireMonitorEvent(IMonitor monitor, int type) {
		IMonitorListener[] obj = monitorListeners.toArray(new IMonitorListener[monitorListeners.size()]);
		
		for (IMonitorListener listener : obj) {
			if (type == ADD)
				listener.monitorAdded(monitor);
			else if (type == CHANGE)
				listener.monitorChanged(monitor);
			else if (type == REMOVE)
				listener.monitorRemoved(monitor);
		}
	}

	protected synchronized void loadMonitors() {
		if (Trace.FINEST) {
			Trace.trace(Trace.STRING_FINEST, "Loading monitors");
		}
		
		monitors = new ArrayList<IMonitor>();
		Preferences prefs = MonitorPlugin.getInstance().getPluginPreferences();
		String xmlString = prefs.getString("monitors");
		if (xmlString != null && xmlString.length() > 0) {
			try {
				ByteArrayInputStream in = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
				IMemento memento = XMLMemento.loadMemento(in);
		
				IMemento[] children = memento.getChildren("monitor");
				if (children != null) {
					int size = children.length;
					for (int i = 0; i < size; i++) {
						Monitor monitor = new Monitor();
						monitor.load(children[i]);
						monitors.add(monitor);
					}
				}
			} catch (Exception e) {
				if (Trace.WARNING) {
					Trace.trace(Trace.STRING_WARNING, "Could not load monitors", e);
				}
			}
		}
	}
	
	protected synchronized void saveMonitors() {
		try {
			ignorePreferenceChanges = true;
			XMLMemento memento = XMLMemento.createWriteRoot("monitors");

			Iterator iterator = monitors.iterator();
			while (iterator.hasNext()) {
				Monitor monitor = (Monitor) iterator.next();
				IMemento child = memento.createChild("monitor");
				monitor.save(child);
			}
			
			String xmlString = memento.saveToString();
			Preferences prefs = MonitorPlugin.getInstance().getPluginPreferences();
			prefs.setValue("monitors", xmlString);
			MonitorPlugin.getInstance().savePluginPreferences();
		} catch (Exception e) {
			if (Trace.SEVERE) {
				Trace.trace(Trace.STRING_SEVERE, "Could not save browsers", e);
			}
		}
		ignorePreferenceChanges = false;
	}
	
	/**
	 * Creates a new resend request from the given request.
	 * 
	 * @param request the request that is to be resent; may not be <code>null</code>
	 * @return a new resend request
	 */
	public static ResendHTTPRequest createResendRequest(Request request) {
		if (request == null)
			throw new IllegalArgumentException();
		return new ResendHTTPRequest((Monitor)request.getMonitor(), request);
	}

	/**
	 * Adds a resend request to this request.
	 * 
	 * @param request the resend request to add
	 * @param resendReq the resend request
	 */
	public void addResendRequest(Request request, ResendHTTPRequest resendReq) {
		if (request == null || resendReq == null)
			return;
		
		List<ResendHTTPRequest> list = null;
		try {
			list = resendMap.get(request);
		} catch (Exception e) {
			// ignore
		}
		
		if (list == null) {
			list = new ArrayList<ResendHTTPRequest>();
			resendMap.put(request, list);
		}
		list.add(resendReq);
	}

	/**
	 * Returns an array of resend requests based on this request. 
	 * 
	 * @param request a request
	 * @return the array of resend requests based on this request
	 */
	public ResendHTTPRequest[] getResendRequests(Request request) {
		List<ResendHTTPRequest> list = resendMap.get(request);
		if (list != null)
			return list.toArray(new ResendHTTPRequest[list.size()]);
		
		return new ResendHTTPRequest[0];
	}

	/**
	 * Start all monitors that are set to auto-start.
	 */
	public synchronized void startMonitors() {
		MonitorManager manager = MonitorManager.getInstance();
		List monitorList = manager.getMonitors();
		Iterator monitorIterator = monitorList.iterator();
		while (monitorIterator.hasNext()) {
			IMonitor monitor = (IMonitor) monitorIterator.next();
			if (monitor.isAutoStart())
				try {
					monitor.start();
				} catch (CoreException e) {
					if (Trace.SEVERE) {
						Trace.trace(Trace.STRING_SEVERE, "Failed to start monitor:" + monitor.toString(), e);
					}
				}
		}
	}
}