/*
 * 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.tsfc.service;
import java.io.FileInputStream;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import meta.ampl.runner.AMPLException;
import meta.ampl.runner.AMPLprocess;
import meta.ampl.runner.AMPLprocessFactory;
import meta.ampl.runner.SolutionStatus;
import meta.ampl.runner.Solver;
import meta.ampl.runner.Variable;
import meta.model.Architecture;
import meta.model.ArchitectureImpl;
import meta.model.ampl.AMPLdata0;
import meta.model.ampl.AMPLmodel0;
import meta.model.ampl.AMPLresults;
import meta.rmi.Argument;
import meta.rmi.Log;
import meta.rmi.Service;
import meta.rmi.ServiceImpl;
import meta.rmi.ServiceRequest;
import meta.rmi.ServiceResponse;
import meta.util.FileUtils;

import org.jdom.Element;


/**
 * All SOA RMI Servers extend the ServiceImpl class and must
 * implement the abstract method execute.
 * 
 */
public class TsfcService extends ServiceImpl  implements Service {
	private static final long	serialVersionUID	= 1L;
	/**
	 * The service description
	 */
	public static final String ServiceDesc = "Thrust Specific Fuel Consumption TSFC Service";
	/**
	 * The service name. This is the RMI bind property
	 */
	public static final String ServiceName = "TSFC";  
	private Properties properties;
	private AMPLprocess process;
    public TsfcService(String d) throws RemoteException, AMPLException {
    	super(d);
    	loadServiceProperties();
    	process = AMPLprocessFactory.create();
    }
	/**
	 * Load the TSFC property file
	 * @throws RemoteException if the properties cannot be read
	 */
	private void loadServiceProperties() throws RemoteException {
		
		// If the property -Dtsfc.properties is set, then this is the pathname
		// to the Fuel consumption property file. If missing, then the default path of
		// "aee.properties" is used
		String props = System.getProperty("tsfc.properties", "tsfc.properties");
		properties = new Properties();
		try {
			properties.load(new FileInputStream(props));
		} catch (IOException ioex) {
			throw new RemoteException(String.format(
					"Error loading property file \"%s\": %s", props, ioex.getMessage()));
		}
	}

	protected void execute() {
		ServiceRequest sr = getServiceRequest();
		List<?> list = sr.getCompositeArg("engine", "architecture");
		if ( list != null) {
		    Element e = (Element) list.get(0);
		    Architecture arch = new ArchitectureImpl(e);
		   
		    try {
		    	String path = System.getProperty("java.io.tmpdir");
			       AMPLmodel0 amplModel = new AMPLmodel0(properties);
				   List<String> model = amplModel.build(arch);
				   String fn = String.format("%s\\%s.mod",path,arch.getName());
				   FileUtils.writeFile(fn,model); 
				   AMPLdata0 amplDat = new AMPLdata0(properties);
				   List<String> data = amplDat.build(arch);
				   fn = String.format("%s\\%s.dat",path,arch.getName());
				   FileUtils.writeFile(fn,data); 
				   process.setModel(model);
				   process.setData(data);
				   process.setSolver(Solver.IPOPT);
			       process.solve();
			       SolutionStatus solutionStatus = process.getSolutionStatus();
			       System.out.println(solutionStatus);
			       Map<String,Variable> map = process.getVariables();
			       AMPLresults results = new AMPLresults(arch,map);
			       Element a = results.outXML();
				   process.reset();
				   getServiceResponse().addContent((Element) a.clone());
				
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		 
	}
	private void errorOut(String msg) throws Exception
	{
		ServiceResponse response = getServiceResponse();
		Log.err(msg);
		response.setStatus(ServiceResponse.BAD_REQUEST);
		response.setStatusMsg(ServiceResponse.BAD_REQUEST_MSG);
		throw new Exception(msg);
	}
 
}
