/*******************************************************************************
 * Copyright (c) 2007,2008 CA, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CA - initial API and implementation
 *     IBM - Fixed bug 216014
 *******************************************************************************/
package org.eclipse.cosmos.internal.dr.drs.service.outputter;

import java.io.PrintWriter;
import java.util.List;

import org.eclipse.cosmos.dc.broker.provisional.client.BrokerClient;
import org.eclipse.cosmos.dc.broker.provisional.client.DataManager;
import org.eclipse.cosmos.dc.broker.provisional.datamodel.Service;
import org.eclipse.cosmos.internal.dr.drs.service.handler.common.ILogger;
import org.eclipse.cosmos.internal.dr.drs.service.handler.common.IOutputterConstants;
import org.eclipse.cosmos.internal.dr.drs.service.handler.common.LoggerWrapper;
import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.AbstractOutputter;
import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.INodeDecorator;
import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.IParameters;


public class BrokerOutputter extends AbstractOutputter implements IOutputterConstants
{
	private static ILogger logger = LoggerWrapper.getLogger(BrokerOutputter.class);
	
//	protected INodeDecorator nodeDecorator = new BrokerNodeDecorator(); 

	public void render(PrintWriter output, IParameters input) throws Exception {
		
		String query = input.getParameter("query"); //$NON-NLS-1$
		String nodeDecoratorStr = input.getParameter("nodeDecorator"); //$NON-NLS-1$
		INodeDecorator nodeDecorator = null;
		if (nodeDecoratorStr != null){
			try {
				nodeDecorator = (INodeDecorator)(Class.forName(nodeDecoratorStr).newInstance());
			} catch (RuntimeException e) {
				logger.warn(e.getMessage(), e);
			}
		}	
		else{
			nodeDecorator = new BrokerNodeDecorator();
		}
		
				
		if ("directMDR".equals(input.getParameter("func"))){ //$NON-NLS-1$ //$NON-NLS-2$
			generateMDRJsonNode(output, nodeDecorator,input.getParameter("name"), input.getParameter("queryservice")); //$NON-NLS-1$ //$NON-NLS-2$
		}else if (query != null && query.equalsIgnoreCase("mdr")) //$NON-NLS-1$
		{			 //$NON-NLS-1$			
			
			// get EPR of the management domain from the deployment descriptor file (web.xml)
			String uri = context.getInitParameter( "BROKER_EPR" ); //$NON-NLS-1$
			BrokerClient brokerclient = new BrokerClient(uri);
			
			//TODO: Nodded to get data mangers that support query services
			List<DataManager> dataManagers = brokerclient.getDataManagerByNamespace(NAMESPACE_QUERY);
			
			// Exclude the federating CMDB itself from the list returned
			String exclude = input.getParameter("exclude");			 //$NON-NLS-1$
			if (exclude != null && !IOutputterConstants.NULL.equals(exclude))
			{
				for (int i = 0, dataManagerCount = dataManagers.size(); i < dataManagerCount; i++)
				{
					DataManager dataManager = dataManagers.get(i);
					String epr = dataManager.getServiceEPR(NAMESPACE_DATAMANAGER);
					if (exclude.equals(epr))
					{
						dataManagers.remove(i);
						break;
					}
				}
			}
						
			// generate JSON for the data manager child nodes
			generateJsonNodeList(output, nodeDecorator, dataManagers, NAMESPACE_QUERY);
			

		} else if (query != null && query.equalsIgnoreCase("cmdbf")){			 //$NON-NLS-1$
			// get EPR of the management domain from the deployment descriptor file (web.xml)
			String uri = context.getInitParameter( "BROKER_EPR" ); //$NON-NLS-1$
			BrokerClient brokerclient = new BrokerClient(uri);
			
			//TODO: Nodded to get data mangers that support cmdbf service
			List<DataManager> dataManagers = brokerclient.getDataManagerByNamespace(NAMESPACE_REGISTRATION);
			
			// generate JSON for the data manager child nodes
			generateJsonNodeList(output, nodeDecorator, dataManagers, NAMESPACE_REGISTRATION);

		} else {
			// get EPR of the management domain from the deployment descriptor file (web.xml)
			String uri = context.getInitParameter( "BROKER_EPR" ); //$NON-NLS-1$
			BrokerClient brokerclient = new BrokerClient(uri);
			
			//TODO: Nodded to get data mangers that support cmdbf service
			List<DataManager> dataManagers = brokerclient.getDataManagers();
			
			// generate JSON for the data manager child nodes
			
			output.print("{ identifier: \"object\",  label: \"title\",  items:[" ); //$NON-NLS-1$
			for (int index=0; index < dataManagers.size(); index++) {
				DataManager dm = dataManagers.get(index);				
				
				String dmName = nodeDecorator.getDisplayName(dm);
				String nodeClass = nodeDecorator.getNodeClass(dm);
//				String properties = nodeDecorator.getProperties(dm);
				if ( index > 0 ){
					output.print(","); //$NON-NLS-1$
				}
				List<Service> services = dm.getServices();
				String serviceStr = ""; //$NON-NLS-1$
				String propertiesStr = ""; //$NON-NLS-1$
				for (int x = 0; x < services.size(); x ++){
					Service service = services.get(x);
					if ( x > 0 ){
						serviceStr+=","; //$NON-NLS-1$
						propertiesStr+=","; //$NON-NLS-1$
					}
					serviceStr += "[\""+service.getNamespace()+"\", \""+service.getEndpointReference()+"\"]"; 					 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					propertiesStr += "[\'"+service.getNamespace()+"\', \'"+service.getEndpointReference()+"\']"; 					 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				}
				
			
				
				output.print("{nodeClass:\"" + nodeClass + "\", title:\"" + dmName + "\"," + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
							 " object:\"dm" + index + "\"," + //$NON-NLS-1$ //$NON-NLS-2$
							 " mdrId:\"" + dm.getId() + "\"," + //$NON-NLS-1$ //$NON-NLS-2$
							 " services:[" + serviceStr + "]"); //$NON-NLS-1$ //$NON-NLS-2$
				//TODO: add more properties on the mdr
				output.print(", store:["); //$NON-NLS-1$
				output.print("['name', '["+dmName+"]']"); //$NON-NLS-1$ //$NON-NLS-2$

				output.print(",['mdrId', '["+dm.getId()+"]']"); //$NON-NLS-1$ //$NON-NLS-2$
				output.print(",['description', '["+dm.getDescription()+"]']"); //$NON-NLS-1$ //$NON-NLS-2$
				output.print(",['soapNamespace', '["+dm.getSoapNamespace()+"]']"); //$NON-NLS-1$ //$NON-NLS-2$
				output.print(",['recordTypeNamespace', '["+dm.getRecordTypeNamespace()+"]']"); //$NON-NLS-1$ //$NON-NLS-2$
				output.print(",['securityNamespace', '["+dm.getSecurityNamespace()+"]']"); //$NON-NLS-1$ //$
				
				output.print(","+propertiesStr); //$NON-NLS-1$ //$NON-NLS-2$
				output.print("]}"); //$NON-NLS-1$
				
			}
			output.print("]}"); //$NON-NLS-1$
		}
	}

	protected void generateJsonNodeList(PrintWriter output, INodeDecorator nodeDecorator, List<DataManager> dataManagers, String namespace){
		// generate JSON for the data manager child nodes
		
		output.print("[" ); //$NON-NLS-1$
		for (int index=0; index < dataManagers.size(); index++) {				
			DataManager dm = dataManagers.get(index);
			String dmName = nodeDecorator.getDisplayName(dm);
			if ( index > 0 ){
				output.print(","); //$NON-NLS-1$
			}
			
			
			//get query service epr
			String queryServiceEPR = dm.getServiceEPR(namespace);//$NON-NLS-1$ 
			String eprString = queryServiceEPR.replace("\n", ""); //$NON-NLS-1$ //$NON-NLS-2$
			output.print("[ \"" + dmName + "\"," + //$NON-NLS-1$ //$NON-NLS-2$
						 " '" + eprString + "', " +			 //$NON-NLS-1$ //$NON-NLS-2$
						 " '" + nodeDecorator.getNodeClass(dm) + "' ]"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		output.print("]"); //$NON-NLS-1$		
	}
	
	protected void generateMDRJsonNode(PrintWriter output,  INodeDecorator nodeDecorator, String dmName, String queryService){
		
		output.print("{ identifier: \"object\",  label: \"title\",  items:[" ); //$NON-NLS-1$
			
			if (dmName == null)
				dmName = nodeDecorator.getDisplayName(null);
			String nodeClass = nodeDecorator.getNodeClass(null);
			
			String serviceStr = "[\"http://cmdbf.org/schema/1-0-0/query\", \""+queryService+"\"]";; //$NON-NLS-1$ //$NON-NLS-2$
			String propertiesStr = "[\'http://cmdbf.org/schema/1-0-0/query\', \'"+queryService+"\']";; //$NON-NLS-1$ //$NON-NLS-2$
			
		
			
			output.print("{nodeClass:\"" + nodeClass + "\", title:\"" + dmName + "\"," + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						 " object:\"dm0\"," + //$NON-NLS-1$ //$NON-NLS-2$
						 " services:[" + serviceStr + "]"); //$NON-NLS-1$ //$NON-NLS-2$
			//TODO: add more properties on the mdr
			output.print(", store:["); //$NON-NLS-1$
			output.print("['name', '["+dmName+"]']"); //$NON-NLS-1$ //$NON-NLS-2$
			output.print(","+propertiesStr); //$NON-NLS-1$ //$NON-NLS-2$
			output.print("]}"); //$NON-NLS-1$
			
		output.print("]}"); //$NON-NLS-1$					
	}
//	public static final void main(String argv[]) throws Exception{
//		IOutputter outputter= new BrokerOutputter();
//		PrintWriter pw = new PrintWriter(System.out);
//		IParameters map = new MapParameterImpl(new HashMap());
//		Map<String, String> contextMap = new HashMap();
//		contextMap.put("BROKER_EPR", "http://bluesky:8080/axis2/services/Broker");
//		EmptyOuttputerContext context = new EmptyOuttputerContext(contextMap);
//		outputter.initalize(context, map);
//		outputter.render(pw, map);
//		pw.flush();
//		pw.close();
//	}	
}
