// Exercise the DiscoveryListener class

package corejini.chapter6;

import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;
import net.jini.discovery.LookupDiscovery;
import net.jini.core.lookup.ServiceRegistrar;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.io.IOException;

public class DiscoveryExample {
    protected LookupDiscovery disco = null;
    protected Listener listener = null;
    protected String[] groups;
    
    class Listener implements DiscoveryListener {
        public void discovered(DiscoveryEvent ev) {
            ServiceRegistrar[] regs = ev.getRegistrars();
        
            for (int i=0 ; i<regs.length ; i++) {
		try {
                    System.out.println("Discovered: ");
                    System.out.println("\tURL:    " + 
				getURL(regs[i]));
                    System.out.println("\tID:     " +  
				regs[i].getServiceID());
                    System.out.println("\tGroups: " + 
				getGroups(regs[i]));
		} catch (RemoteException ex) {
		    System.err.println("Error: " + 
					ex.getMessage());
		    disco.discard(regs[i]);
		}
            }
        }
            
        public void discarded(DiscoveryEvent ev) {
            ServiceRegistrar[] regs = ev.getRegistrars();
        
            for (int i=0 ; i<regs.length ; i++) {
		try {
                    System.out.println("Discarded: ");
                    System.out.println("\tURL:    " + 
				    getURL(regs[i]));
		} catch (RemoteException ex) {
		    System.err.println("Error: " +
					ex.getMessage());
		}
            }
        }
    }
    
    public DiscoveryExample(String[] groups) {
        this.groups = groups;
    }
   
    public static String getURL(ServiceRegistrar reg) 
		throws RemoteException {
        return reg.getLocator().toString();
    }

    public static String getGroups(ServiceRegistrar reg) 
		throws RemoteException {
        String[] groups = reg.getGroups();

        if (groups.length == 0) {
            return "<none>";
        }

        StringBuffer buf = new StringBuffer();
        for (int i=0 ; i<groups.length ; i++) {
            if (groups[i] == null) {
                buf.append("NULL ");
            } else if (groups[i].equals("")) {
                buf.append("PUBLIC ");
            } else {
                buf.append(groups[i]);
            }
        }
        return buf.toString();
    }
    
    synchronized void startDiscovery() throws IOException {
        if (disco == null) {
	    listener = new Listener();
            disco = new LookupDiscovery(groups);
            disco.addDiscoveryListener(listener);
        }
    }
    
    synchronized void stopDiscovery() throws IOException {
        if (disco != null) {
            disco.removeDiscoveryListener(listener);
            disco.setGroups(LookupDiscovery.NO_GROUPS);
            disco = null;
        }
    }
    
    public static void main(String[] args) {
        String[] groups;
        int index = 0;

	if (System.getSecurityManager() == null) {
	    System.setSecurityManager(new RMISecurityManager());
	}
        
        if (args.length == 0) {
            groups = LookupDiscovery.ALL_GROUPS;
        } else {
            groups = new String[args.length];
        }
        
        for (int i=0 ; i<args.length ; i++) {
            if (args[i].equals("all")) {
                groups = LookupDiscovery.ALL_GROUPS;
                break;
            } else if (args[i].equals("none")) {
                groups = LookupDiscovery.NO_GROUPS;
                break;
            } else if (args[i].equals("public")) {
                groups[index++] = "";
            } else {
                groups[index++] = args[i];
            }
        }
        
        try {
            DiscoveryExample ex = 
			new DiscoveryExample(groups);
            ex.startDiscovery();
        
            System.out.println("Hit return to terminate " +
				"discovery.");
        
            while (((char) System.in.read()) != '\n')
                /* loop */ ;
        
            System.out.println("Terminating discovery.");
            ex.stopDiscovery();
        } catch (IOException ex) {
            System.err.println("Problems with discovery: " + 
				ex.getMessage());
        }
    }
}
