/*
 * Delivered to the U.S. Government in Accordance with Contract FA8650-10-C-7080.
 *
 * EXPORT CONTROLLED
 * ECCN#   EAR99
 * Warning: This document contains technical data which is controlled under the
 * Bureau of Industry & Security's Export Administration Regulations and may not be
 * exported or re-exported without authorization by the Bureau of Industry & Security.
 * Diversion contrary to US law is prohibited.
 *
 * (c) 2011 United Technologies Corp.
 * Developed with the sponsorship of the Defense Advanced Research Projects Agency (DARPA).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this data,
 * including any software or models in source or binary form, as well as any drawings, 
 * specifications, and documentation (collectively "the Data"), to deal in the Data without 
 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Data, and to permit persons to whom the Data
 * is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Data.
 *
 * THE DATA IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS, SPONSORS, DEVELOPERS, CONTRIBUTORS, OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE DATA OR THE
 * USE OR OTHER DEALINGS IN THE DATA.
*/

package proxy.clients;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

import meta.rmi.Service;
import meta.rmi.ServiceResponse;
import proxy.ArgumentProxyElement;
import proxy.ProxyElement;
import proxy.ServiceResponseCompositeProxyElement;
import exception.ControllerException;

/**
 * A proxy to the AEE service
 */
public class AeeProxy extends SOAProxy {
	private String  host;
	private Service service;

	/**
	 * Constructor
	 *
	 * @param host Where the AEE service is running
	 */
	public AeeProxy(String host) {
		this.host    = host;
		this.service = null;
	}

	@Override
	public Service getService() throws MalformedURLException, RemoteException, NotBoundException {
		if (service == null)
			service = (Service) Naming.lookup(String.format("rmi://%s/aee", host));
		return service;
	}
	
	/**
	 * Invoke the new configuration method on the AEE
	 * @param platform           The platform name
	 * @param level              The current level
	 * @param platformResponse   The response from the repository's getPlatform
	 * @return  The first architecture
	 * @throws ControllerException if any error setting the new configuration
	 */
	public ServiceResponse newConfiguration(final String platform,
			                                    String level,
			                                    ServiceResponse platformResponse)
		throws ControllerException {
		final String[]     types = (level.equals("1"))?
			                         new String[]{"devicetable",
				                                    "flowtable",
				                                    "inputtable",
				                                    "outputtable",
				                                    "devicerules",
				                                    "flowrules"}
		                       :   new String[]{"devicetable",
                                            "flowtable",
                                            "inputtable",
                                            "outputtable",
                                            "devicerules"};
		List<ProxyElement> args = new ArrayList<ProxyElement>(types.length+1);
		for (int i = 0; i < types.length; i++) {
			final int j = i;
			args.add(new ServiceResponseCompositeProxyElement(platformResponse) {
				@Override
				public String getElementName() { return platform; }
				@Override
				public String getElementType() { return types[j]; }
			});
		}
		args.add(new ArgumentProxyElement("level","int",level,""));
		return run("NewConfiguration", args);
	}

	/**
	 * Get the next architecture from the AEE
	 * @return  The next architecture
	 * @throws ControllerException if any error getting the next architecture
	 */
	public ServiceResponse getNextArchitecture() throws ControllerException {
		return run("GetNextArchitecture", new ArrayList<ProxyElement>(0));
	}
	
	/**
	 * Shutdown the AEE
	 * @return The shutdown response
	 * @throws ControllerException if any error shutting the AEE down
	 */
	public ServiceResponse shutdown() throws ControllerException {
		return run("Shutdown", new ArrayList<ProxyElement>(0));
	}
}
