// RoadTransportationGeographicRelationshipPropertyFileSpecification.java
package org.eclipse.stem.internal.data.geography.infrastructure.transportation.specifications;

/*******************************************************************************
 * Copyright (c) 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;

import org.eclipse.emf.common.util.URI;
import org.eclipse.stem.core.STEMURI;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.stem.core.graph.Edge;
import org.eclipse.stem.core.graph.EdgeLabel;
import org.eclipse.stem.core.graph.Graph;
import org.eclipse.stem.core.graph.impl.EdgeImpl;
import org.eclipse.stem.definitions.labels.LabelsFactory;
import org.eclipse.stem.definitions.labels.PopulationLabel;
import org.eclipse.stem.definitions.labels.RelativePhysicalRelationship;
import org.eclipse.stem.definitions.labels.RelativePhysicalRelationshipLabel;
import org.eclipse.stem.definitions.labels.RelativePhysicalRelationshipLabelValue;
import org.eclipse.stem.definitions.labels.TransportRelationshipLabel;
import org.eclipse.stem.definitions.labels.TransportRelationshipLabelValue;
import org.eclipse.stem.definitions.transport.PipeStyleTransportSystem;
import org.eclipse.stem.definitions.transport.PipeTransportEdge;
import org.eclipse.stem.definitions.transport.PipeTransportEdgeLabel;
import org.eclipse.stem.definitions.transport.PipeTransportEdgeLabelValue;
import org.eclipse.stem.definitions.transport.TransportFactory;
import org.eclipse.stem.geography.names.ISOKey;
import org.eclipse.stem.internal.data.geography.infrastructure.transportation.propertydata.AirTransportGeographicRelationshipPropertyData;
import org.eclipse.stem.internal.data.propertydata.PropertyData;
import org.eclipse.stem.internal.data.propertydata.RelationshipPropertyData;

/**
 * This class represents the specification of air transportation 
 */

public class AirTransportationGeographicRelationshipPropertyFileSpecification
		extends TransportationGeographicRelationshipPropertyFileSpecification {

	
	public final static String AIR_TRANSPORT_PATTERN = "transport/pipe";
	public final static String AIR_TRANSPORT_SYSTEM = "(S)";
	/**
	 * This is the name used to identify "air" edges.
	 */
	public final static String AIR_TRANSPORTATION_EDGE_NAME = "air"; //$NON-NLS-1$
	

	/** Key defining the mode of transport */
	public static final String TRANSPORTATION_MODE_PROPERTY = "TRANSPORT_MODE"; //$NON-NLS-1$

	/** Key defining the type of population transported by this network */
	public static final String POPULATION_ID_PROPERTY = "POPULATION_IDENTIFIER"; //$NON-NLS-1$

	/** The property specifying the time period rates are defined over */
	public static final String RATE_TIME_PERIOD_PROPERTY = "RATE_TIME_PERIOD"; //$NON-NLS-1$

	/** The property specifying the average time someone spends in the network */
	public static final String AVG_TIME_IN_SYSTEM_PROPERTY = "AVG_TIME_IN_SYSTEM"; //$NON-NLS-1$

	private String transportationMode;
	private String populationIdentifier;
	private int rateTimePeriod; // in milliseconds
	@SuppressWarnings("unused")
	private double averageTimeInSystem;
	
	/**
	 * @param properties
	 *            the set of properties that specify the {@link Identifiable}
	 *            
	 * @override
	 */
	@Override
	protected void collectPropertyDataSet(final Properties properties) {
		// This will set the properties in this instance and also remove the
		// non-data properties from the set such as the dublin core properties
		// and the RECORD_CLASSNAME_PROPERTY
		collectNonDataProperties(properties);

		// Collect air transportation unique properties
		transportationMode = properties.getProperty(
				TRANSPORTATION_MODE_PROPERTY).trim();
		populationIdentifier = properties.getProperty(
				POPULATION_ID_PROPERTY).trim();
		rateTimePeriod = Integer.parseInt(properties.getProperty(
				RATE_TIME_PERIOD_PROPERTY).trim());
		averageTimeInSystem = Double.parseDouble(properties.getProperty(
				AVG_TIME_IN_SYSTEM_PROPERTY).trim());

		properties.remove(TRANSPORTATION_MODE_PROPERTY);
		properties.remove(POPULATION_ID_PROPERTY);
		properties.remove(RATE_TIME_PERIOD_PROPERTY);
		properties.remove(AVG_TIME_IN_SYSTEM_PROPERTY);
		
		// Now we process the data entries and create the data set
		for (final Entry<Object, Object> entry : properties.entrySet()) {
			final String dataPropertyKey = (String) entry.getKey();

			final PropertyData data = createPropertyDataInstanceFromProperty(
					dataPropertyKey, ((String) entry.getValue()).trim());
			// Did we get null because of some error?
			if (data != null) {
				// No
				propertyDataSet.add(data);
			}
		} // for each property
	} // collectPropertyDataSet
	
	/**
	 * @see org.eclipse.stem.internal.data.specifications.RelationshipGraphPropertyFileSpecification#createEdgeLabel(org.eclipse.stem.internal.data.propertydata.RelationshipPropertyData)
	 */
	@Override
	protected EdgeLabel createEdgeLabel(
			RelationshipPropertyData relationshipGraphData) {

		final AirTransportGeographicRelationshipPropertyData airData = (AirTransportGeographicRelationshipPropertyData) relationshipGraphData;

		final TransportRelationshipLabel retValue = LabelsFactory.eINSTANCE
				.createTransportRelationshipLabel();

		retValue.setURI(createRelationshipEdgeLabelURI(relationshipGraphData));
		final TransportRelationshipLabelValue currentValue = LabelsFactory.eINSTANCE
				.createTransportRelationshipLabelValue();
		currentValue.setAvailableDepartureCapacityProportion(airData.getArrivalRate()); // TODo, what is this?

		retValue.setCurrentValue(currentValue);
		return retValue;
	} // createEdgeLabel

	/**
	 * @see org.eclipse.stem.internal.data.specifications.RelationshipGraphPropertyFileSpecification#getRelationshipName()
	 */
	@Override
	protected String getRelationshipName() {
		return AIR_TRANSPORTATION_EDGE_NAME;
	}

   
	/**
	 * @see org.eclipse.stem.internal.data.specifications.IdentifiablePropertyFileSpecification#createPropertyDataInstanceFromProperty(java.lang.String,
	 *      java.lang.String)
	 */
	@Override
	protected PropertyData createPropertyDataInstanceFromProperty(
			String propertyKey, String propertyValue) {
		AirTransportGeographicRelationshipPropertyData retValue = null;
		try {
			retValue = new AirTransportGeographicRelationshipPropertyData(propertyKey,propertyValue);
		} catch (ParseException e) {
			e.printStackTrace();
			System.err.println("Key:"+propertyKey+" Value:"+propertyValue); //$NON-NLS-1$ //$NON-NLS-2$
			System.err.println(e.getMessage());
		}
		return retValue;
	} // createPropertyDataInstanceFromProperty

	/**
	 *  Populate the air transport in graph
	 * @override
	 */
	@Override
	protected void initializeIdentifiableFromPropertyDataSet(
			Identifiable identifiable, List<PropertyData> propertyDataSet) {
		final Graph graph = (Graph)identifiable;

		// Hash map to collect transport system nodes
		// The key is the ISO Key for the transport system level.
		final HashMap<ISOKey, PipeStyleTransportSystem> transportSystemNodes = new HashMap<ISOKey, PipeStyleTransportSystem>();

		final HashMap<ISOKey, Double> transportSystemMaxCapacity = getTransportSystemCapacity(propertyDataSet);
		
		List<PropertyData>dataSet = propertyDataSet;
				
		// Process each of the data set records, each one contains two ISOKeys,
		// the first one (enclosing) is the key that matches the transportation
		// system, the second one is the key of the region the transportation
		// system connects to so that population members can move in and out of
		// the region. The second key also represents a transportation 
		// system so that people can move in and out of those when the model
		// has lower level regions. The for loop goes through each record, creating the
		// transportation system for the first ISO key if it doesn't exist and
		// then the "migration" edges that connect it to the region and air transport system
		for (final PropertyData dataSetData : dataSet) {
			final AirTransportGeographicRelationshipPropertyData pipeTransportData = (AirTransportGeographicRelationshipPropertyData) dataSetData;

			// Get the transportation system node, creating it if necessary
			PipeStyleTransportSystem transportSystem = transportSystemNodes
					.get(pipeTransportData.getTransportationSystemISOKey());

			// Does a transportation system exist for the enclosing node?
			if (transportSystem == null) {
				// No
				// Make one then...
				ISOKey newSystemKey = pipeTransportData.getTransportationSystemISOKey();
				double maxCapacity = transportSystemMaxCapacity.get(newSystemKey);
				
				transportSystem = createTransportSystem(newSystemKey, 0, maxCapacity);
				
				// ...put it in the map
				transportSystemNodes.put(newSystemKey, transportSystem);
				// ...and the graph
				graph.putNode(transportSystem);

				// The region contains the air transport system
				//graph.putEdge(createContainmentEdge(pipeTransportData,
				//		transportSystem));
			} // if a transport system exists

			// The URI of the region node that the transportation system will
			// migrate population members to and from.
			final org.eclipse.emf.common.util.URI regionNodeURI = createNodeURI(pipeTransportData
					.getTransportationSystemISOKey(), pipeTransportData
					.getRegionISOKey());

			// Population migrates into the network from the air transport system at the rate of departure
			// rate/air transport system population
			final double fromNodeMaxFlow = pipeTransportData.getDepartureRate();

			// Population migrates into the network from the air transport system  at the rate of departure
			// rate/air transport system population
			final double toNodeMaxFlow = pipeTransportData.getArrivalRate();

			// The migration edge from the region to the transportation system
			PipeTransportEdge fromEdge = createPipeTransportEdge(
					regionNodeURI, transportSystem.getURI(),
					fromNodeMaxFlow, pipeTransportData);
			graph.putEdge(fromEdge);
			
			// The migration edge to the region from the transportation system
			PipeTransportEdge toEdge = createPipeTransportEdge(
					transportSystem.getURI(), regionNodeURI,
					toNodeMaxFlow, pipeTransportData);
			graph.putEdge(toEdge);
			
			// Now create edges to the lower level transportation system. It might now
			// exist, but such dangling edges will be removed eventually
			
			final org.eclipse.emf.common.util.URI transportNodeURI = createTransportSystemURI(pipeTransportData.getRegionISOKey());
			fromEdge = createPipeTransportEdge(
					transportNodeURI, transportSystem.getURI(),
					fromNodeMaxFlow, pipeTransportData);
			graph.putEdge(fromEdge);
			
			toEdge = createPipeTransportEdge(
					transportSystem.getURI(), transportNodeURI,
					toNodeMaxFlow, pipeTransportData);
			graph.putEdge(toEdge);
		} // for each data set record
	} // populateFromNonDataProperties
	
	protected HashMap<ISOKey, Double> getTransportSystemCapacity(List<PropertyData> propertyDataSet) {
		HashMap<ISOKey, Double> result = new HashMap<ISOKey, Double>();
		
		for (final PropertyData dataSetData : propertyDataSet) {
			final AirTransportGeographicRelationshipPropertyData pipeTransportData = (AirTransportGeographicRelationshipPropertyData) dataSetData;
			ISOKey tskey = pipeTransportData.getTransportationSystemISOKey();
			double rate = (pipeTransportData.getArrivalRate() + pipeTransportData.getDepartureRate()) / 2;
			
			if(result.containsKey(tskey)) {
				result.put(tskey, result.get(tskey)+rate);
			} else result.put(tskey, rate);
		}
		return result;
	}
		
	/** Need to create the central node for the pipe-style network */
	protected PipeStyleTransportSystem createTransportSystem(
			final ISOKey systemISOKey, final double startingPop, final double maxCapacity) {
		// Create the central node
		final PipeStyleTransportSystem retValue = TransportFactory.eINSTANCE
				.createPipeStyleTransportSystem();

		// Set properties. e.g. the identifier, etc.
		// The URI
		final String uriString = PipeStyleTransportSystem.URI_TYPE_PIPE_STYLE_TRANSPORT_SYSTEM
				+ "/" + systemISOKey.toString(); //$NON-NLS-1$
		retValue.setURI(STEMURI.createURI(uriString));

		// The population label
		final PopulationLabel populationLabel = LabelsFactory.eINSTANCE
				.createPopulationLabel();
		populationLabel.setPopulationIdentifier(getPopulationIdentifier());
		populationLabel.getCurrentPopulationValue().setCount(startingPop);
		populationLabel.setIdentifiable(retValue);
		populationLabel.setPopulatedArea(1.0);
		populationLabel.setURI(STEMURI.createURI(PopulationLabel.URI_TYPE_POPULATION_LABEL_SEGMENT+"/"+getPopulationIdentifier()+"/"+systemISOKey));
		retValue.getLabels().add(populationLabel);

		retValue.setMaxCapacity(maxCapacity);
		return retValue;
	} // createTransportSystem
	
	protected URI createTransportSystemURI(
			final ISOKey systemISOKey) {
		// Set properties. e.g. the identifier, etc.
		// The URI
		final String uriString = PipeStyleTransportSystem.URI_TYPE_PIPE_STYLE_TRANSPORT_SYSTEM
				+ "/" + systemISOKey.toString(); //$NON-NLS-1$
		URI result = STEMURI.createURI(uriString);
		return result;
	}
	/**
	 * @return the population identifier
	 */
	public final String getPopulationIdentifier() {
		return populationIdentifier;
	}

	
	private PipeTransportEdge createPipeTransportEdge(final org.eclipse.emf.common.util.URI fromURI,
			final org.eclipse.emf.common.util.URI toURI, final double maxFlow, AirTransportGeographicRelationshipPropertyData propertyData) {
		final PipeTransportEdge edge = TransportFactory.eINSTANCE.createPipeTransportEdge();
		edge.setNodeAURI(fromURI);
		edge.setNodeBURI(toURI);

		edge.setURI(createRelationshipEdgeURI(propertyData, fromURI, toURI));
		PipeTransportEdgeLabel label =  TransportFactory.eINSTANCE.createPipeTransportEdgeLabel();
		PipeTransportEdgeLabelValue labelval =  TransportFactory.eINSTANCE.createPipeTransportEdgeLabelValue();
		label.setURI(createRelationshipEdgeLabelURI(propertyData, fromURI, toURI));
		labelval.setMaxFlow(maxFlow);
		labelval.setTimePeriod(this.rateTimePeriod);
		label.setCurrentValue(labelval);
		edge.setLabel(label);

		return edge;
	} // createMigrationEdge
	
	private URI createRelationshipURI(String segment,
			AirTransportGeographicRelationshipPropertyData propertyData,
			URI fromURI, URI toURI) {
		// final GeographicRelationshipPropertyData geoRelationshipPropertyData = (GeographicRelationshipPropertyData) propertyData;
		final StringBuilder sb = new StringBuilder(segment);
		sb.append("/"); //$NON-NLS-1$
		sb.append("relationship"); //$NON-NLS-1$
		sb.append("/"); //$NON-NLS-1$
		sb.append(getRelationshipName());
		sb.append("/"); //$NON-NLS-1$
		String first = fromURI.toString().contains(AIR_TRANSPORT_PATTERN) ? AIR_TRANSPORT_SYSTEM+fromURI.lastSegment() : fromURI.lastSegment();
		sb.append(first);
		sb.append("_"); //$NON-NLS-1$
		String second = toURI.toString().contains(AIR_TRANSPORT_PATTERN) ? AIR_TRANSPORT_SYSTEM+toURI.lastSegment() : toURI.lastSegment();
		sb.append(second);
		sb.append(getRelationshipSpecifier(propertyData));

		return STEMURI.createURI(sb.toString());
	}

	private URI createRelationshipEdgeLabelURI(	AirTransportGeographicRelationshipPropertyData propertyData,
			URI fromURI, URI toURI) {
		return createRelationshipURI("label", propertyData, fromURI, toURI);
	}
	private URI createRelationshipEdgeURI(
			AirTransportGeographicRelationshipPropertyData propertyData,
			URI fromURI, URI toURI) {
		return createRelationshipURI("edge", propertyData, fromURI, toURI);
	}

	/**
	 * 
	 * @param pipeTransportData
	 * @param transportSystem
	 * @return
	 */
	@SuppressWarnings("unused")
	private Edge createContainmentEdge(
			final AirTransportGeographicRelationshipPropertyData pipeTransportData,
			final PipeStyleTransportSystem transportSystem) {
		final Edge retValue = EdgeImpl.createEdge(createNodeURI(isoKeyB,
				pipeTransportData.getTransportationSystemISOKey()), transportSystem
				.getURI(), true);

		final RelativePhysicalRelationshipLabel containLabel = LabelsFactory.eINSTANCE
				.createRelativePhysicalRelationshipLabel();

		containLabel.setURIOfIdentifiableToBeLabeled(retValue.getURI());
		containLabel.getCurrentRelationship().setRelationship(
				RelativePhysicalRelationship.CONTAINS_LITERAL);

		final RelativePhysicalRelationshipLabelValue currentValue = LabelsFactory.eINSTANCE
				.createRelativePhysicalRelationshipLabelValue();
		currentValue.setAdjacent(false);
		currentValue
				.setRelationship(RelativePhysicalRelationship.CONTAINS_LITERAL);
		containLabel.setCurrentValue(currentValue);

		// create the uri;
		final StringBuilder sb = new StringBuilder(
				"edge/relationship/relativephysical/"); //$NON-NLS-1$
		sb.append(pipeTransportData.getTransportationSystemISOKey());
		sb.append("_"); //$NON-NLS-1$
		sb.append(pipeTransportData.getTransportationSystemISOKey());
		sb.append("-"); //$NON-NLS-1$
		sb.append(transportationMode);
		sb.append("/"); //$NON-NLS-1$
		sb.append(RelativePhysicalRelationship.CONTAINS_LITERAL.toString()
				.toLowerCase());

		retValue.setURI(STEMURI.createURI(sb.toString()));
		containLabel.setURI(STEMURI.createURI(sb.toString()));
		retValue.setLabel(containLabel);
		containLabel.setURIOfIdentifiableToBeLabeled(retValue.getURI());
		return retValue;
	} // createContainmentEdge
	
} // AirTransportationGeographicRelationshipPropertyFileSpecification