/*
 * 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.aee;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import meta.ampl.runner.AMPLException;
import meta.model.Architecture;
import meta.model.ArchitectureImpl;
import meta.model.Device;
import meta.model.Flow;
import meta.model.Link;
import meta.util.FileUtils;

import meta.util.StringUtils;

public class AEE   {
	private final String PATH = "data\\AEEoutput";
	private final String DEVICE_FILE = "data\\AEEoutput\\AEEOutput_Devices.txt";
	private final String FLOW_FILE = "data\\AEEoutput\\AEEOutput_Flows.txt";
	private List<String> linkTableFiles;
	private Iterator<String> iterLinkTableFiles;
	private ArchitectureImpl arch;
	
	public AEE() {
		getCandidateArchitectures();
	}
	/**
	 * Find the candidate architectures
	 */
	private void getCandidateArchitectures() {
		
		  File folder = new File(PATH);
		  String[] listOfFiles = folder.list( 
				  new FilenameFilter() {
					  public boolean accept(File f,String name) {
						  if ( name.startsWith("AEEOutput_LT")) return true;
						  return false;
					  }
				  });
		  linkTableFiles = Arrays.asList(listOfFiles);  
		  iterLinkTableFiles = linkTableFiles.iterator();
	}
    public Architecture getNextArchitecture() throws AMPLException {
    	if (! iterLinkTableFiles.hasNext() ) return null;
    	String linkTable = iterLinkTableFiles.next();
     	arch = new ArchitectureImpl(linkTable);
     	examineNodeTable(linkTable);
     	devices();
     	flows();
     	links(linkTable);
     	//System.out.println(linkTable);
    	return arch;
    }
    private void examineNodeTable(String linkTable) throws AMPLException {
    	// use the link table name to get the node table name
    	// because they are similar.
    	String name = linkTable.replace("LT", "NT");
    	String nodeFile =  String.format("%s\\%s", PATH,name);
    	List<String> lines = FileUtils.read(nodeFile);
    	boolean findEmbedded = StringUtils.find(lines, "Embedded");
    	arch.setEmbeddedEngine(findEmbedded);
    	boolean findSingleProp = StringUtils.find(lines, "Single_Rear_Prop");
    	boolean findMultProp = StringUtils.find(lines, "Multiple_Rear_Props");
    	if ( findSingleProp) arch.setRearProp(true);
    	if ( findMultProp) arch.setRearProp(true);
    	boolean findProp = StringUtils.find(lines, "Prop");
    	if ( findProp ) arch.setEngineType("turboprop");
    	boolean findFan = StringUtils.find(lines, "Fan");
    	if ( findFan) arch.setEngineType("turbofan");
    	arch.setNodeTable(lines);
    }
    private void devices() throws AMPLException {
    	 
    	List<String> lines = FileUtils.read(DEVICE_FILE);
    	for (String line : lines) {
			String[] s = line.split("\\s+");
			Integer id = Integer.valueOf(s[0]);
			Device device = new Device(s[1],id);
			arch.add(device);
		}
    }
    private void flows() throws AMPLException {
    	List<String> lines = FileUtils.read(FLOW_FILE);
    	for (String line : lines) {
			String[] s = line.split("\\s+");
			Integer id = Integer.valueOf(s[0]);
			Flow flow = new Flow(s[1],id);
			arch.add(flow);
		}
    }
    private void links(String name) throws AMPLException {
    	String linkFile =  String.format("%s\\%s", PATH,name);
    	List<String> lines = FileUtils.read(linkFile);
    	lines.remove(0);
		for (String line : lines) {
			String[] s = line.split("\\s+");
			Integer o = Integer.valueOf(s[1]);
			Integer d = Integer.valueOf(s[2]);
			Integer t = Integer.valueOf(s[3]);
			if (  t.intValue() == 2 )  {  // ignore mechanical flow
				boolean rearProp = arch.hasRearProp();  
				if ( ! rearProp ) continue;   // unless there is a prop in the rear
			}
			Device source = arch.getDevice(o);
			Device sink = arch.getDevice(d);
			Flow flow = arch.getFlow(t);
			Link link = new Link(source,sink,flow);
			arch.add(link);
		}
    }
}
