/*
 * AidaTreeServantTest.java
 *
 * Created on October 16, 2003, 10:48 PM
 */

package hep.aida.ref.remote.testRemote;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import hep.aida.dev.IDevMutableStore;

import hep.aida.ref.remote.RemoteConnectionException;
import hep.aida.ref.remote.RemoteUpdateEvent;
import hep.aida.ref.remote.interfaces.AidaTreeClient;
import hep.aida.ref.remote.interfaces.AidaTreeServant;
import hep.aida.ref.remote.interfaces.AidaTreeServer;
import hep.aida.ref.remote.interfaces.AidaUpdateEvent;

/**
 * This is a very simple implementation of AidaTreeServant 
 * that just delegates most of the methods to the TestUtils class.
 *
 * @author  serbo
 */

public class AidaTreeServantTest implements AidaTreeServant{
    
    private Map hash;
    private AidaTreeClient client;
    private boolean duplex;
    public static long serverUpdateInterval;
    private boolean connected;
    private Thread thread;
    private boolean keepRunning;
    private String nodeType = "RemoteManagedObjectTest";
    
    /** Creates a new instance of AidaTreeServantTest */
    public AidaTreeServantTest(AidaTreeClient client) {
        this(client, true);
    }
    
    public AidaTreeServantTest(AidaTreeClient client, boolean duplex) {
        this(client, duplex, -1);
    }
    
    public AidaTreeServantTest(AidaTreeClient client, boolean duplex, long serverUpdateInterval) {
        this.client = client;
        this.duplex = duplex;
        this.serverUpdateInterval = serverUpdateInterval;
        initServantTest();
    }

    
    // Service methods
    
    public void initServantTest() {
        this.connected = false;
        if (hash != null) hash.clear();
        else hash = new Hashtable();
        keepRunning = true;
        if (duplex && serverUpdateInterval > 0) startUpdateThread();
    }
    
    // Start separate thread to notify Store about updates
    // for all known objects. This simulates updates comming
    // from the remote server.
    public void startUpdateThread() {
        thread = new Thread(new Runnable() {
            public void run() {
                while (duplex && keepRunning) {
                    try { 
                        Thread.sleep(serverUpdateInterval);
                    } catch (Exception e) { e.printStackTrace(); }
                    AidaUpdateEvent[] events = createUpdateEvents();
                    client.stateChanged(events);
                }
            }
        });  
        thread.start();
    }
    
    
    public boolean disconnect() {
        serverUpdateInterval = 1;
        keepRunning = false;
        connected = false;
        if (hash != null) hash.clear();
        hash = null;
        thread = null;
        client = null;
        return true;        
    }
    
    private AidaUpdateEvent[] createUpdateEvents() {
        AidaUpdateEvent[] events = null;
        synchronized (hash) {
            if (!hash.isEmpty()) {
                int size = hash.size();
                events = new AidaUpdateEvent[size];
                int i = 0;
                Iterator it = hash.keySet().iterator();
                while (it.hasNext()) {
                    String path = ((String) it.next());
                    events[i] = new RemoteUpdateEvent(AidaUpdateEvent.NODE_UPDATED, path, nodeType);
                    i++;
                }
            }
        } // End synchronized
        return events;
    }
    
    
    // AidaTreeServant methods
    
    public java.lang.Object find(String path) {
        Object obj = TestUtils.find(path);
        hash.put(path, obj);        
        return obj;
    }    
    
    public String[] listObjectNames(String path) {
        return TestUtils.listObjectNames(path);   
    }    
    
    public String[] listObjectTypes(String path) {
        return TestUtils.listObjectTypes(path); 
    }
    
    // setValid should allow updates to be sent out for those nodes
    // You should call server.setValid(nodePath) when the client is ready to 
    // receive updates for this node.
    // Do nothing here for now.
    public void setValid(String[] nodePaths) {
        //System.out.println("AidaTreeServantTest.setValid for "+nodePaths.length+" nodes:");
        //for (int i=0; i<nodePaths.length; i++) System.out.println("\t\t\t\tpath="+nodePaths[i]);
    }
    
    public AidaUpdateEvent[] updates() {
        AidaUpdateEvent[] events = createUpdateEvents();
        return events;
    }    
    
}
