/* $ID: $
 * Created on 28.07.2003
 *
 */
package de.skyrix.zsp.conf;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;

import javax.swing.event.EventListenerList;

import de.skyrix.zsp.event.ConfigChangeEvent;
import de.skyrix.zsp.event.ConfigChangeListener;

/**Manages the ZideStoreProxy configuration
 * 
 * @author sell
 * @version $Revision: 1.1 $
 */
public class ZSPConfig {
	private static Properties properties = null;
	/**Container for the event listeners*/
	private static EventListenerList listeners;

	public ZSPConfig() {
	}

	/**Checks the configuration.
	 * 
	 * @return <code>null</code> if configuration is ok,
	 *         otherwise an error message.
	 */
	public static String checkConfig() {
		// filter out empty entries
		Enumeration propertyEnumeration = properties.keys();
		while (propertyEnumeration.hasMoreElements()) {
			try {
				String key = (String) propertyEnumeration.nextElement();
				if (getProperty(key) == null || "".equals(getProperty(key).trim()))
					properties.remove(key);
			}
			catch (Exception e) {
			}

		}

		if (getProperty("zidestore_url") == null)
			return "Missing zidestore url.";
		else if (!getProperty("zidestore_url").endsWith("/"))
			setProperty("zidestore_url", getProperty("zidestore_url") + "/");

		if (!"true".equals(ZSPConfig.getProperty("detectAuthKey"))) {
			if (getProperty("zidestore_user") == null)
				return "Missing zidestore user.";
			if (getProperty("zidestore_password") == null)
				return "nopw";
		}
		if (getProperty("cache_dir") == null)
			setProperty("cache_dir", System.getProperty("user.home") + "/zspcache");
		if (getProperty("proxy_port") == null)
			return "Missing proxy port.";
		if (getProperty("enable_spider") == null)
			setProperty("enable_spider", "false");
		else if (getProperty("spider_interval") == null)
			setProperty("spider_interval", "5");

		return null;
	}

	public static boolean initWithArguments(String[] args) {
		loadConfig();
		if (args == null)
			return true;

		for (int i = 0; i < args.length; i++) {
			try {
				if ("-u".equals(args[i])) {
					setProperty("zidestore_user", args[i + 1]);
				}
				else if ("-D".equals(args[i])) {
					setProperty("cache_dir", args[i + 1]);
				}
				else if ("--no-spider".equals(args[i])) {
					setProperty("enable_spider", "false");
				}
				else if ("-i".equals(args[i])) {
					setProperty("spider_interval", args[i + 1]);
				}
				else if ("-p".equals(args[i])) {
					setProperty("proxy_port", args[i + 1]);
				}
				else if ("--configure".equals(args[i])) {
					System.setProperty("zsp.configMode", "true");
					return true;
				}
				else if ("--init-cache".equals(args[i])) {
					setProperty("spider_interval", "0");
					setProperty("enable_spider", "false");
					System.setProperty("zsp.initMode", "true");
					return true;
				}
				else if ("--empty-cache".equals(args[i])) {
					System.setProperty("zsp.cleanMode", "true");
					return true;
				}
				else if ("-U".equals(args[i])) {
					String url = args[i + 1];
					if (!url.endsWith("/"))
						url += "/";

					setProperty("zidestore_url", url);

				}
				else {
					System.out.println("Invalid argument: " + args[i]);
					return false;
				}
			}
			catch (Exception e) {
				return false;
			}
		}
		return true;
	}

	public static void loadConfig() {
		if (properties == null)
			properties = new Properties();

		String configFile = System.getProperty("zsp.config_file");

		try {
			properties.load(new FileInputStream(configFile));
		}
		catch (FileNotFoundException e) {
			System.err.println(
				"Config file " + configFile + " not found, loading defaults");
			//setDefaults();
		}
		catch (IOException e) {
			System.err.println(
				"Unable to read from config file "
					+ configFile
					+ ", loading defaults");
			//setDefaults();
		}
	}

	public static void storeConfig() {
		if (properties == null)
			return;

		String configFile = System.getProperty("zsp.config_file");

		try {
			properties.store(
				new FileOutputStream(configFile),
				"ZideStoreProxy configuration file");
		}
		catch (FileNotFoundException e) {
			System.err.println("Unable to create config file " + configFile);
		}
		catch (IOException e) {
			System.err.println("Unable to write to config file " + configFile);
		}
    notifyConfigChangeListeners();
	}

	public static void removeProperty(String key) {
		if (properties == null)
			return;

		properties.remove(key);
	}

	public static void setProperty(String key, String value) {
		if (properties == null)
			return;

		properties.setProperty(key, value);
	}

	public static String getProperty(String key) {
		if (properties == null)
			return null;

		return properties.getProperty(key, null);
	}

	/**Register a <code>ConfigChangeListener</code>.
	 * 
	 * @param listener - the listener
	 */
	public static void addConfigChangeListener(ConfigChangeListener listener) {
		if (listener == null)
			return;

		if (listeners == null)
			listeners = new EventListenerList();
		listeners.add(ConfigChangeListener.class, listener);
	}

	/**Removes a previously registered <code>ConfigChangeListener</code>.
	 * 
	 * @param listener the listener to remove
	 */
	public static void removeProxyStateLister(ConfigChangeListener listener) {
		if (listener == null || listeners == null)
			return;

		listeners.remove(ConfigChangeListener.class, listener);
	}

	/**Notifies all registered <code>ConfigChangeListener</code>
	 * that the configuration has changed.
	 * <p>This method is internaly used by zsp's config management.
	 * Do not manualy use it.</p>
	 */
	private static void notifyConfigChangeListeners() {
		if (listeners != null
			&& listeners.getListenerCount(ConfigChangeListener.class) > 0) {
			Object[] lobj = listeners.getListenerList();

			for (int i = 0; i < lobj.length; i++) {
				if (lobj[i] instanceof ConfigChangeListener) {
					ConfigChangeEvent event = new ConfigChangeEvent(new ZSPConfig(), 100);
					((ConfigChangeListener) lobj[i]).configurationChanged(event);
				}
			}
		}
	}
}
