package guiDomain;
import sharedInterfaces.*;

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

public class DataServerHandler
{
    DataServerFacadeInterface dataServer; //The current data server
    DataServerHandler nextHandler;        //The next handler in the chain
    static String defaultExperiment, defaultShot;

    DataServerHandler(DataServerFacadeInterface dataServer, 
                      DataServerHandler nextHandler)
    {
        this.dataServer = dataServer;
        this.nextHandler = nextHandler;
    }

    public DataServerFacadeInterface openExperiment(String experiment, 
                              int shot) throws IOException
    {
        try 
        {
            dataServer.open(experiment, shot);
            //If we reach this statement, no exception has been 
            //generated and the open operation was successful.
            return dataServer;
        }
	catch(Exception exc)
	{
            if(nextHandler != null) //if no more handlers in the chain
                return nextHandler.openExperiment(experiment, shot);
            throw new IOException("No data server supports this experiment");
	}
    }

    //This static method returns the handler chains based on their 
    //definitions in EScope.properties
    static public DataServerHandler getDataServerHandlerChain()
    {
        DataServerHandler currHandler = null;
        String factoryClassName;
        Properties properties = new Properties();
        try
        {
            properties.load(new FileInputStream("EScope.properties"));
        }
        catch (Exception exc)
        {
            System.err.println("Cannot read property file");
            return null;
        }
        int idx = 0;
        //Scan property file:

	// (default experiment and shot)
        defaultExperiment = properties.getProperty("DataServer.Experiment");
        defaultShot = properties.getProperty("DataServer.Shot");
	if (defaultExperiment==null) defaultExperiment="";
	if (defaultShot==null) defaultShot="";

	// servers
        while (true)
        {
            idx++;
            factoryClassName = properties.getProperty
                           ("DataServer_" + idx + ".FactoryClass");

            if (factoryClassName == null) //Finished scanning properties
                return currHandler;
            try
            {
                Class factoryClass = Class.forName(factoryClassName);
                DataServerFactoryInterface factory = 
                     (DataServerFactoryInterface) factoryClass.newInstance();

		//check for a list of comma-separated arguments for 
                //data server factory method
                String namesList = properties.getProperty("DataServer_" + 
                               idx + ".Args");
		String[] args = new String[0];
                if(namesList != null)
                {
                    StringTokenizer st = new StringTokenizer(namesList, ", ");
                    args = new String[st.countTokens()];
                    for(int i = 0; i < args.length; i++)
                        args[i] = st.nextToken();
                }

                DataServerFacadeInterface dataServer = 
                     factory.createDataServer(args);
                String source = properties.getProperty("DataServer_" + idx +
                    ".Source");
                dataServer.connect(source);//connecting to all sources is slow?
                //If we reach this statement everything was OK
                currHandler = new DataServerHandler(dataServer, currHandler);
            }
            catch (Exception exc)
            {
                System.err.println("Error adding Data Server " +
                                   factoryClassName + " : " + exc);
            }
        }
    }

    public String getExperiment() { return defaultExperiment;}
    public String getShot() { return defaultShot;}

}
