/*
 * 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 main;

import meta.rmi.ServiceResponse;

import org.jdom.Attribute;
import org.jdom.Element;

import proxy.ArchitectureProxyElement;
import proxy.FuelConsumptionProxy;
import proxy.MissionProxy;
import proxy.clients.AeeProxy;
import proxy.clients.FcProxy;
import proxy.clients.TsfcProxy;
import proxy.clients.RepositoryProxy;
import exception.ControllerException;

/**
 * The top level controller
 */
public class Controller {
	
 
	private static final String RepositoryHost = "localhost";
	private static final String AeeHost        = "localhost";
	private static final String FcHost         = "localhost";
	private static final String TsfcHost       = "localhost";

	/**
	 * @param args 0) The platform name
	 *             1) The level
	 *             2) Mission name
	 */
	public static void main(String[] args) {
		if (args.length != 3) {
			System.out.println("Usage: Controller platform level mission");
			System.exit(1);
		}
		String platform = args[0];
		String level    = args[1];
		String mission  = args[2];
		
		// The services we'll need
		RepositoryProxy repository = new RepositoryProxy(RepositoryHost);
		AeeProxy        aee        = new AeeProxy(AeeHost);
		FcProxy         fc         = new FcProxy(FcHost);
		TsfcProxy       tsfc       = new TsfcProxy(TsfcHost);
		try {
			
			// Get the platform definition and mission data
			ServiceResponse response    = repository.getPlatform(platform, level);
			MissionProxy    missionData = new MissionProxy(repository.getMission(mission));
			
			// Set the new configuration
			response = aee.newConfiguration(platform, level, response);
			while (hasArchitecture(response)) {
				ArchitectureProxyElement arch = new ArchitectureProxyElement(response);
				
				// Invoke the TSFC level 0 - Return the arch plus data for devices
				if ( level.equals("0")) {
				  response = tsfc.calcTsfc(platform, arch, missionData);
				  ArchitectureProxyElement arch2 = new ArchitectureProxyElement(response);
				  repository.storeArchitectures(platform, level, arch2);
				}
				// Invoke the FCS level 1			
				// If feasible, publish results to the repository
				if ( level.equals("1")) {
					repository.storeArchitectures(platform, level, arch);
				   	
				  response = fc.fuelConsumption(platform, arch, missionData);
				  FuelConsumptionProxy fcResult = new FuelConsumptionProxy(response,
						                                                     platform);
				  
				  	repository.storeArchitectures(platform, level, arch);
					repository.storeResult(fcResult, level, arch);
				 
				  
				}
				// Get the next architecture
				response = aee.getNextArchitecture();
			}			
		} catch (ControllerException ex) {
			System.out.println(ex.getMessage());
			ex.printStackTrace();
			System.exit(2);
		}

	}
	
	/**
	 * Check that the response contains an architecture
	 * @param response The service response. Should contain an architecture,
	 *                 even an empty one
	 * @return true if a valid architecture
	 */
	private static boolean hasArchitecture(ServiceResponse response) {
		boolean                  hasArch = false;
		ArchitectureProxyElement proxy   = new ArchitectureProxyElement(response);
		try {			
			// Could be an empty architecture. Note that all architectures have an id
			Element                arch    = proxy.getElement();
			Attribute              id      = arch.getAttribute("id");
			hasArch                        = (id != null);
			
		} catch (ControllerException cex) {
			// no architecture
		}
		return hasArch;
	}

}
