/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: WireQualityMetric.java
 *
 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 *
 * Electric(tm) is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Electric(tm) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.sun.electric.tool.routing.metrics;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.network.Network;
import com.sun.electric.database.text.Version;
import com.sun.electric.database.topology.ArcInst;
import com.sun.electric.tool.routing.metrics.WireQualityMetric.QualityResults;
import com.sun.electric.util.ElapseTimer;
import com.sun.electric.util.TextUtils;

/**
 * @author Felix Schmidt
 * 
 */
public class WireQualityMetric extends RoutingMetric<QualityResults> {

	private static Logger logger = LoggerFactory.getLogger(WireQualityMetric.class);
	ElapseTimer timer;
	String name = WireQualityMetric.class.getName();
	boolean regression = false; // to print some info only in regression mode.

	public WireQualityMetric() {}
	public WireQualityMetric(String s, ElapseTimer t) 
	{name = s; timer = t; regression = true;}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.sun.electric.tool.routing.metrics.RoutingMetric#calculate(com.sun
	 * .electric.database.hierarchy.Cell)
	 */
	@Override
	public QualityResults calculate(Cell cell) {
		QualityResults result = new QualityResults();
		InetAddress addr;
		try {
			addr = InetAddress.getLocalHost();
			String hostname = addr.getHostName();
			Date now = new Date();
			
			logger.debug("============================");
			
			// print machine/version/date only when it is used in regression mode
			if (regression)
			{
				logger.debug("metric name: " + name);
				logger.debug("machine: " + hostname);
				logger.debug("date: " + TextUtils.formatDate(now));
				logger.debug("Electric's version: " + Version.getVersion());
			}
			if (timer != null)
				logger.debug("execution time: " + timer);
	        logger.trace("calculate wire length");
	        // assumption is that all wires are routing wires
	        result.wireLength = new WireLengthMetric().calculate(cell);
	        logger.debug("wire length metric: " + result.wireLength);
	
	        logger.trace("calculate unrouted nets");
	        result.unroutedSegments = new UnroutedNetsMetric().calculate(cell);
	        logger.debug("unrouted nets metric: " + result.unroutedSegments);
	
			logger.trace("calculate via amount metric...");
			result.vias = new ViaAmountMetric().calculate(cell);
			logger.debug("via amount metric: " + result.vias);
	
			logger.trace("calculate stacked via amount metric...");
			result.stackedVias = new StackedViasAmountMetric().calculate(cell);
			logger.debug("stacked via amount metric: " + result.stackedVias);
	
			logger.trace("calculate detouring amount metric...");
			result.detourings = new DetouringAmountMetric().calculate(cell);
			logger.debug("detouring amount metric: " + result.detourings);
	
			logger.trace("calculate evenness metric...");
			result.evenness = new EvennessMetric().calculate(cell);
			logger.debug("evenness metric: " + result.evenness);
	
			logger.debug("============================");
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public static class QualityResults {
		public Integer vias;
		public Integer stackedVias;
		public Integer detourings;
		public Double evenness;
        public Double wireLength;
        public Integer unroutedSegments;
	}

	/* (non-Javadoc)
	 * @see com.sun.electric.tool.routing.metrics.RoutingMetric#reduce(java.lang.Object, com.sun.electric.database.topology.ArcInst)
	 */
	@Override
	protected QualityResults reduce(QualityResults result, ArcInst instance, Network net) {
		// [fschmidt] method not required here
		throw new UnsupportedOperationException();
	}

}
