// MobyDigestClient.java
//
// Created: September 2004
//
// This file is a component of the BioMoby project.
// Copyright Martin Senger (martin.senger@gmail.com).
//

import org.biomoby.client.CmdLineHelper;
import org.biomoby.shared.CentralCached;
import org.biomoby.shared.MobyDataType;
import org.biomoby.shared.MobyNamespace;
import org.biomoby.shared.MobyService;
import org.biomoby.shared.MobyServiceType;
import org.biomoby.shared.MobyData;
import org.biomoby.shared.MobySecondaryData;
import org.biomoby.shared.MobyPrimaryDataSet;
import org.biomoby.shared.event.SimpleListener;

import org.tulsoft.tools.BaseCmdLine;

import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;

/**
 * A simple client retrieving and printing cummulative (digestive)
 * registry entries. It can collaborate with the locally cached
 * registry entries. <p>
 *
 * @author <A HREF="mailto:martin.senger@gmail.com">Martin Senger</A>
 * @version $Id: MobyDigestClient.java,v 1.9 2008/03/02 12:45:25 senger Exp $
 */

public class MobyDigestClient
    extends CmdLineHelper {

    /*************************************************************************
     *
     * Entry point...
     *
     *************************************************************************/
    public static void main (String [] args) {
	try {

	    BaseCmdLine cmd = getCmdLine (args, MobyDigestClient.class);

	    // where is a Moby registry
	    CentralCached worker = getCachableRegistryWorker (cmd);

	    // how much to show
	    boolean details = cmd.hasOption ("-details");
	    boolean summary = cmd.hasOption ("-summary");
	    boolean verbose = (cmd.hasOption ("-v") || cmd.hasOption ("-verbose"));
	    if (verbose)
		worker.addNotificationListener (new SimpleListener());

	    // read (sometimes all) data types and their relationships
	    if (cmd.hasOption ("-d")) {
		if (details) {
		    MobyDataType[] dataTypes = worker.getDataTypes();
		    for (int i = 0; i < dataTypes.length; i++) {
			msgln (dataTypes[i].toString());
			msgln ("---");
		    }
		} else {
		    Map dataTypeNames = worker.getDataTypeNames();
		    for (Iterator it = dataTypeNames.entrySet().iterator(); it.hasNext(); ) {
			Map.Entry entry = (Map.Entry)it.next();
			msgln (entry.getKey());
		    }
		}
	    }

	    // read all service types and their relationships
	    if (cmd.hasOption ("-t")) {
		MobyServiceType[] serviceTypes = worker.getFullServiceTypes();
		for (int i = 0; i < serviceTypes.length; i++) {
		    if (details)
			msgln (serviceTypes[i]);
		    else
			msgln (serviceTypes[i].getName());
		}
	    }

	    // read all services
	    if (cmd.hasOption ("-s")) {
		if (details || summary) {
		    MobyService[] services = worker.getServices();
		    if (details) {
			for (int i = 0; i < services.length; i++) {
			    msgln (services[i]);
			    msgln ("---");
			}
		    } else {  // summary
			msgln
			    ("#Prim\t#Sec\tSType\t#Out\tInColl\tOutColl\tService\tAuthority");
			for (int i = 0; i < services.length; i++) {
			    MobyService service = services[i];
			    MobyData[] pInputs = service.getPrimaryInputs();
			    MobyData[] sInputs = service.getSecondaryInputs();
			    MobyData[] outputs = service.getPrimaryOutputs();
			    msg (pInputs.length + "\t");
			    msg (sInputs.length + "\t");
			    StringBuffer buf = new StringBuffer();
			    Set<String> set = new HashSet<String>();
			    for (int j = 0; j < sInputs.length; j++) {
				String abbrev =
				    ( ((MobySecondaryData)sInputs[j]).getDataType()
				      .substring (0, 1));
				if (! set.contains (abbrev)) {
				    buf.append (abbrev);
				    set.add (abbrev);
				}
			    }
			    msg (buf + "\t");
			    msg (outputs.length + "\t");
			    boolean found = false;
			    for (int j = 0; j < pInputs.length; j++) {
				if (pInputs[j] instanceof MobyPrimaryDataSet) {
				    found = true;
				    break;
				}
			    }
			    msg (found + "\t");
			    found = false;
			    for (int j = 0; j < outputs.length; j++) {
				if (outputs[j] instanceof MobyPrimaryDataSet) {
				    found = true;
				    break;
				}
			    }
			    msg (found + "\t");
			    msg (service.getName() + "\t");
 			    msgln (service.getAuthority());
			}
		    }
		} else {
		    Map authorities = worker.getServiceNamesByAuthority();
		    for (Iterator it = authorities.entrySet().iterator(); it.hasNext(); ) {
			Map.Entry entry = (Map.Entry)it.next();
			String authority = (String)entry.getKey();
			String[] names = (String[])entry.getValue();
			for (int i = 0; i < names.length; i++) {
			    msgln (names[i] + " (" + authority + ")");
			}
		    }
		}
	    }

	    // read all namespaces
	    if (cmd.hasOption ("-n")) {
		MobyNamespace[] namespaces = worker.getFullNamespaces();
		for (int i = 0; i < namespaces.length; i++) {
		    if (details)
			msgln (namespaces[i]);
		    else
			msgln (namespaces[i].getName());
		}
	    }

	} catch (Throwable e) {
	    processErrorAndExit (e);
	}
    }
}
