package org.wikiwebserver.distribute.se;

import java.awt.HeadlessException;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

import org.wikiwebserver.distribute.interfaces.RemoteWorker;
import org.wikiwebserver.distribute.se.gui.JMainGUI;


public class RemoteWorkerApp {
	
	private static RemoteWorker worker;
	
	public static void main(String[] args) {
		
		ConfigManager configMan = new ConfigManager();
		
		// Wait for configuration to load
		synchronized (configMan) {
	        new Thread(configMan).start();		    
			try { configMan.wait();
			} catch (InterruptedException ex) {}
		}
		
        ResourceManager resourceMan = new ResourceManager();
        
        // Wait for resource to load
        synchronized (resourceMan) {
            new Thread(resourceMan).start();
            try { resourceMan.wait();
            } catch (InterruptedException ex) {}
        }		
        
		
		// Override configuration with command line settings
		for (String arg : args) {
			int sep = arg.indexOf("="); 
		  	if (sep > 0 && sep < arg.length()) {
		  		ConfigManager.setString(arg.substring(0, sep), arg.substring(sep+1));
		  	}
		}	
		
		// Install a custom class loader for loading new tasks
		ClassLoader workerClassLoader = setupClassLoader();
		Thread.currentThread().setContextClassLoader(workerClassLoader);	
		
		
		
		try {
			URL fileSharingUrl = ConfigManager.getFileSharingUrl();
			if (fileSharingUrl == null) {
				System.out.println("Configuration incomplete, no files are shared.");
			}
			else {
				File rootFile = ConfigManager.getFileForPath("/").getCanonicalFile();
				System.out.println("Sharing " + rootFile + " at " + fileSharingUrl);
			}
			
		} catch (IOException ex) {
			String msg = "Malformed file sharing root path";
			RuntimeException rex = new RuntimeException(msg);
			rex.initCause(ex);
			throw rex;
		}


		

		// Schedule a job for the event-dispatching thread to create and show GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
        		try {                	
        			JMainGUI.createAndShowGUI();
        		}
        		catch (HeadlessException ex) {
        		    System.err.println("No graphics available to display GUI, continuing...");
        		    //ex.printStackTrace();
        		}            			
            }
        });

        
		// Start requesting and executing tasks from the server
		RemoteWorkerLoader workerLoader = new RemoteWorkerLoader();
		Thread workerThread = new Thread(workerLoader);
		workerThread.setContextClassLoader(workerClassLoader);
		workerThread.start();
		
		worker = workerLoader.getRemoteWorker(); // Will wait until worker has started
	}
	

	
	private static ClassLoader setupClassLoader() {
		
		// Add support for loading external class files
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		try {
			URL[] taskClassUrls = { new URL(ConfigManager.getString("taskClassServerUrl")) };
			return URLClassLoader.newInstance(taskClassUrls, classLoader);
		} 
		catch (MalformedURLException ex){
			ex.printStackTrace();
		}

		return classLoader;
	}	

	public static RemoteWorker getWorker() {
		return worker;
	}

}

