/*
 * 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 meta.rmi.server;

import java.io.FileInputStream;
import java.io.IOException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Properties;

import meta.aee.service.AeeService;
import meta.tsfc.service.TsfcService;
import meta.fuelconsumption.service.FuelConsumptionService;
import meta.repository.service.RepositoryService;

/**
 * Register service programs with the bootstrap registry service
 */
public class Server {
	public static final String FUEL_CONSUMPTION = "Fuel Consumption Service";
	private Properties properties;
	private Registry registry;
	public static void main(String[] args) throws Exception {	
	   new Server().start();
	}
	private Server() {
		loadServiceNames();
	}
	private void start() throws Exception {
		startRMIregistry();
		startTsfcService();
	 	startFuelConsumptionService();
	 	startAeeService();
		startRepositoryService();
	}
	/**
	 * Start the RMI Registry 
	 * 
	 * LocateRegistry.createRegistry is preferred over rmiregistry.exe
	 * The application may experience RMI bind exceptions at startup if 
	 * rmiregistry.exe doesn't finish its initialization before 
	 * meta.Server attempts to bind the remote services:
	 * (aee, fcc, repository, tsfc)
     *
	 * @throws Exception if any Remote exception
	 */
	private void startRMIregistry() throws RemoteException {
	 registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
     print("RMI Registry");
	}
	
	/**
	 * Start the fuel consumption service
	 * @throws Exception if any Remote exception
	 */
	private void startFuelConsumptionService() throws Exception {
		FuelConsumptionService server_fcs = new FuelConsumptionService(FUEL_CONSUMPTION);			
		String fcs = properties.getProperty("FUEL_CONSUMPTION");
		Naming.bind(fcs,server_fcs);
		print(FUEL_CONSUMPTION);
	}
	/**
	 * Start the TSFC service
	 * @throws Exception if any Remote exception
	 */
	private void startTsfcService() throws Exception {
		TsfcService server = new TsfcService(TsfcService.ServiceDesc);			
		String     name   = properties.getProperty(TsfcService.ServiceName);
		Naming.bind(name, server);
		print(TsfcService.ServiceDesc);
	}
	
	/**
	 * Start the AEE service
	 * @throws Exception if any Remote exception
	 */
	private void startAeeService() throws Exception {
		AeeService server = new AeeService(AeeService.ServiceDesc);			
		String     name   = properties.getProperty(AeeService.ServiceName);
		Naming.bind(name, server);
		print(AeeService.ServiceDesc);
	}
	
	/**
	 * Start the Repository service
	 * @throws Exception if any Remote exception
	 */
	private void startRepositoryService() throws Exception {
		RepositoryService server = new RepositoryService(RepositoryService.ServiceDesc);			
		String     name   = properties.getProperty(RepositoryService.ServiceName);
		Naming.bind(name, server);
		print(RepositoryService.ServiceDesc);
	}
	
	private void print(String s) {
		String msg = String.format("%s started",s);
		System.out.println(msg);
	}
	private void loadServiceNames() {
		
		// If the property -Dservices.properties is set, then this is the 
		// pathname to the Server property file. If missing, then the default 
		// path of "services.properties" is used
		String props = System.getProperty("services.properties", 
				                              "services.properties");

		properties = new Properties();
		try {
		    properties.load(new FileInputStream(props));
		} catch (IOException e) {
			System.out.format("RMI Services failed to start. File \"%s\" not found%n", props);
			System.exit(1);
		}

	}
}
