package com.featheredtoast.javad;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.swing.Timer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class JavaD {

    private Log log = LogFactory.getLog(this.getClass());
	
    private String directoryPath;
	
    private Properties properties;
	
    private Timer timer;
	
    private int interval = 60000;

    private String systemVar = null;
	
    public JavaD(String directoryPath) throws IOException {
        this.directoryPath = directoryPath;
        properties = new Properties();
        loadPropertiesInDirectory();
    }
	
    public JavaD(String directoryPath, int interval) throws IOException {
        this.directoryPath = directoryPath;
        this.interval = interval;
        properties = new Properties();
        loadPropertiesInDirectory();
    }
	
    public JavaD(String directoryPath, Properties defaults) throws IOException {
        this.directoryPath = directoryPath;
        properties = new Properties(defaults);
        loadPropertiesInDirectory();
    }
	
    public JavaD(String directoryPath, Properties defaults, int interval) throws IOException {
        this.directoryPath = directoryPath;
        this.interval = interval;
        properties = new Properties(defaults);
        loadPropertiesInDirectory();
    }

    public void addLoadFromSystemProperty(String envVar) throws IOException {
        this.systemVar = envVar;
        loadPropertiesInDirectory();
    }
	
    public synchronized void start() {
        startJavaD();
    }
	
    public synchronized void stop() {
        if(timer != null) {
            timer.stop();
        }
    }
	
    public Properties getProperties() {
        return properties;
    }
	
    public void resetProperties(Properties properties) {
        this.properties = new Properties(properties);
    }
	
    private void startJavaD() {
        ActionListener al = new ActionListener() {
			
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        loadPropertiesInDirectory();
                    } catch (IOException e1) {
                        log.warn("error loading properties", e1);
                    }
                }
            };
        log.debug("properties javad starting");
        timer = new Timer(interval, al);
        timer.setRepeats(true);
        timer.start();
    }
	
    private synchronized void loadPropertiesInDirectory() throws IOException {
        File dir = new File(directoryPath);
		
        if(dir.isDirectory()) {
            File[] propertyFiles = dir.listFiles(new FilenameFilter() {
                    @Override
                    public boolean accept(File arg0, String arg1) {
                        return arg1.endsWith(".properties");
                    }
                });
            for(File file : propertyFiles) {
                loadProperteisInFile(file);
            }
        }
    }
	
    private void loadProperteisInFile(File propertyFile) throws IOException {
        log.debug("loading properties: " + propertyFile.getName());
        InputStream is = new FileInputStream(propertyFile);
        Properties newFileProperties = new Properties();
        newFileProperties.load(is);
        is.close();
        Properties newEnvironmentProperties = new Properties();
        if(systemVar != null) {
            log.debug(systemVar);
            String environmentPropertyString = System.getenv(systemVar);
            if(environmentPropertyString == null ||
               "".equals(environmentPropertyString)) {
            	environmentPropertyString = System.getProperty(systemVar);
            }
            log.debug(environmentPropertyString);
            if(environmentPropertyString != null) {
                newEnvironmentProperties = parseEnvironmentProperty(environmentPropertyString);
            }
        }
        properties.putAll(newFileProperties);
        properties.putAll(newEnvironmentProperties);
    }

    private Properties parseEnvironmentProperty(String propertyString) {
        Properties newEnvironmentProperties = new Properties();
        String[] propertyKeyValues = propertyString.split(";");
        for(String keyValue : propertyKeyValues) {
            String[] keyValueArray = keyValue.trim().split(" ");
            if(keyValueArray.length >= 2) {
                String key = keyValueArray[0].trim();
                String value = keyValueArray[1].trim();
                log.debug("setting system property " + key + " " + value);
                newEnvironmentProperties.setProperty(key, value);
            }
        }
        return newEnvironmentProperties;
    }
}

@@ -787,32 +787,40 @@
 ();%0A        load
+External
 PropertiesInDire
@@ -809,35 +809,24 @@
 alProperties
-InDirectory
 ();%0A    %7D%0A%09%0A
@@ -1020,32 +1020,40 @@
 ();%0A        load
+External
 PropertiesInDire
@@ -1042,35 +1042,24 @@
 alProperties
-InDirectory
 ();%0A    %7D%0A%09%0A
@@ -1234,32 +1234,40 @@
 s);%0A        load
+External
 PropertiesInDire
@@ -1256,35 +1256,24 @@
 alProperties
-InDirectory
 ();%0A    %7D%0A%09%0A
@@ -1496,32 +1496,40 @@
 s);%0A        load
+External
 PropertiesInDire
@@ -1518,35 +1518,24 @@
 alProperties
-InDirectory
 ();%0A    %7D%0A%0A 
@@ -1603,32 +1603,79 @@
 s IOException %7B%0A
+        log.debug(%22adding envvar: %22 + envVar);%0A
         this.sys
@@ -1695,32 +1695,40 @@
 ar;%0A        load
+External
 PropertiesInDire
@@ -1717,35 +1717,24 @@
 alProperties
-InDirectory
 ();%0A    %7D%0A%09%0A
@@ -2330,24 +2330,32 @@
         load
+External
 PropertiesIn
@@ -2352,27 +2352,16 @@
 operties
-InDirectory
 ();%0A    
@@ -2706,24 +2706,32 @@
 ed void load
+External
 PropertiesIn
@@ -2732,19 +2732,8 @@
 ties
-InDirectory
 () t
@@ -2796,19 +2796,16 @@
 yPath);%0A
-%09%09%0A
         
@@ -3206,32 +3206,67 @@
     %7D%0A        %7D%0A
+        loadEnvironmentProperty();%0A
     %7D%0A%09%0A    priv
@@ -3572,24 +3572,122 @@
 is.close();%0A
+        properties.putAll(newFileProperties);%0A    %7D%0A%0A    private void loadEnvironmentProperty() %7B%0A
         Prop
@@ -4296,54 +4296,8 @@
   %7D%0A
-        properties.putAll(newFileProperties);%0A
     

load environment var when no properties exist