/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
*/
package org.apache.uima.ducc.ws;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.uima.ducc.cli.ws.json.MachineFacts;
import org.apache.uima.ducc.cli.ws.json.MachineFactsList;
import org.apache.uima.ducc.cli.ws.json.NodePidList;
import org.apache.uima.ducc.common.ConvertSafely;
import org.apache.uima.ducc.common.IDuccEnv;
import org.apache.uima.ducc.common.Node;
import org.apache.uima.ducc.common.node.metrics.NodeUsersInfo;
import org.apache.uima.ducc.common.node.metrics.NodeUsersInfo.NodeProcess;
import org.apache.uima.ducc.common.utils.DuccLogger;
import org.apache.uima.ducc.common.utils.DuccLoggerComponents;
import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
import org.apache.uima.ducc.common.utils.TimeStamp;
import org.apache.uima.ducc.common.utils.id.DuccId;
import org.apache.uima.ducc.transport.event.NodeMetricsUpdateDuccEvent;
import org.apache.uima.ducc.transport.event.ProcessInfo;
import org.apache.uima.ducc.ws.MachineInfo.MachineStatus;
import org.apache.uima.ducc.ws.db.DbQuery;
import org.apache.uima.ducc.ws.db.IDbMachine;
import org.apache.uima.ducc.ws.server.DuccWebProperties;
import org.apache.uima.ducc.ws.types.Ip;
import org.apache.uima.ducc.ws.types.NodeId;
import org.apache.uima.ducc.ws.types.UserId;
import org.apache.uima.ducc.ws.utils.DatedNodeMetricsUpdateDuccEvent;

/**
 * A class to manage information about machines comprising data
 * from Agents and Resource Manager (RM).  The former report
 * via node metrics publications the later reports via database.
 */
public class DuccMachinesData {

	private static DuccLogger logger = DuccLoggerComponents.getWsLogger(DuccMachinesData.class.getName());
	private static DuccId jobid = null;
	
	private static ConcurrentSkipListMap<MachineInfo,NodeId> sortedMachines = new ConcurrentSkipListMap<MachineInfo,NodeId>();
	private static ConcurrentSkipListMap<NodeId,MachineInfo> unsortedMachines = new ConcurrentSkipListMap<NodeId,MachineInfo>();
	private static ConcurrentSkipListMap<NodeId,MachineSummaryInfo> summaryMachines = new ConcurrentSkipListMap<NodeId,MachineSummaryInfo>();
	
	private static AtomicLong memTotal = new AtomicLong(0);
	private static AtomicLong memFree = new AtomicLong(0);
	private static AtomicLong swapInuse = new AtomicLong(0);
	private static AtomicLong swapFree = new AtomicLong(0);
	
	private static DuccMachinesData duccMachinesData = new DuccMachinesData();
	
	private static ConcurrentSkipListMap<Ip,NodeId> ipToNameMap = new ConcurrentSkipListMap<Ip,NodeId>();
	private static ConcurrentSkipListMap<NodeId,Ip> nameToIpMap = new ConcurrentSkipListMap<NodeId,Ip>();
	private static ConcurrentSkipListMap<String,String> isSwapping = new ConcurrentSkipListMap<String,String>();
	
	private static ConcurrentSkipListMap<String,TreeMap<String,NodeUsersInfo>> ipToNodeUsersInfoMap = new ConcurrentSkipListMap<String,TreeMap<String,NodeUsersInfo>>();
	
	private static MachineFactsList machineFactsList = new MachineFactsList();
	
	public static DuccMachinesData getInstance() {
		return duccMachinesData;
	}
	
	public boolean isMachineSwapping(String ip) {
		return isSwapping.containsKey(ip);
	}
	
	public Map<MachineInfo,NodeId> getMachines() {
		return getSortedMachines();
	}
	
	public Map<MachineInfo,NodeId> getSortedMachines() {
		Map<MachineInfo,NodeId> retVal = new TreeMap<MachineInfo,NodeId>();
		retVal.putAll(sortedMachines);
		return retVal;
	}
	
	private long down_fudge = 10;
	private long DOWN_AFTER_SECONDS = WebServerComponent.updateIntervalSecondsNormal + down_fudge;
	private long SECONDS_PER_MILLI = 1000;
	
	private long getAgentMillisMIA() {
		String location = "getAgentMillisMIA";
		long millisMIA = DOWN_AFTER_SECONDS*SECONDS_PER_MILLI;
		Properties properties = DuccWebProperties.get();
		String s_tolerance = properties.getProperty("ducc.rm.node.stability");
		String s_rate = properties.getProperty("ducc.agent.node.metrics.publish.rate");
		try {
			long tolerance = Long.parseLong(s_tolerance.trim());
			long rate = Long.parseLong(s_rate.trim());
			long secondsRM = (tolerance * rate) / SECONDS_PER_MILLI;
			logger.trace(location, jobid, "default:"+DOWN_AFTER_SECONDS+" "+"secondsRM:"+secondsRM);
			if(DOWN_AFTER_SECONDS < secondsRM) {
				millisMIA = secondsRM * SECONDS_PER_MILLI;
			}
		}
		catch(Throwable t) {
			logger.warn(location, jobid, t);
		}
		return millisMIA;
	}
	
	private void determineStatus(MachineInfo mi, IDbMachine dbMachine) {
		String location = "determineStatus";
		if(dbMachine != null) {
			// determine defined/down/up based on DB
			Boolean responsive = dbMachine.getResponsive();
			Boolean online = dbMachine.getOnline();
			Boolean blacklisted = dbMachine.getBlacklisted();
			MachineStatus machineStatus = MachineStatus.Down;
			if(responsive) {
				if(online) {
					if(!blacklisted) {
						machineStatus = MachineStatus.Up;
					}
				}
			}
			mi.setMachineStatus(machineStatus);
			mi.setResponsive(responsive);
			mi.setOnline(online);
			mi.setBlacklisted(blacklisted);
			StringBuffer sb = new StringBuffer();
			sb.append(mi.getName());
			sb.append(" ");
			sb.append(mi.getMachineStatus());
			sb.append(" ");
			sb.append(mi.getMachineStatusReason());
			sb.append(" ");
			String text = sb.toString().trim();
			logger.trace(location, jobid, text);
			mi.setQuantum(dbMachine.getQuantum());
		}
		else {
			// determine defined/down/up based on Agent
			if(mi.getElapsedSeconds() < 0) {
				mi.setMachineStatus(MachineStatus.Defined);
			}
			else if(mi.isExpired(getAgentMillisMIA())) {
				mi.setMachineStatus(MachineStatus.Down);
			}
			else {
				mi.setMachineStatus(MachineStatus.Up);
			}
		}
	}
	
	private Map<String, IDbMachine> getDbMapMachines() {
		String location = "getDbMapMachines";
		Map<String, IDbMachine> retVal = null;
		try {
			DbQuery dbQuery = DbQuery.getInstance();
			//if(!dbQuery.isEnabled()) {
				retVal = dbQuery.getMapMachines();
			//}
		}
		catch(Exception e) {
			logger.error(location, jobid, e);
		}
		return retVal;
	}
	
	private IDbMachine getDbMachine(Map<String, IDbMachine> dbMapMachines, NodeId nodeId) {
		String location = "getDbMachine";
		IDbMachine retVal = null;
		try {
			if(dbMapMachines != null) {
				if(nodeId != null) {
					String name = nodeId.getLongName();
					retVal = dbMapMachines.get(name);
				}
			}
		}
		catch(Exception e) {
			logger.error(location, jobid, e);
		}
		return retVal;
	}
	
	private static void setSortedMachines(ConcurrentSkipListMap<MachineInfo,NodeId> value) {
		sortedMachines = value;
	}
	
	public void updateSortedMachines() {
		String location = "updateSortedMachines";
		logger.debug(location, jobid, "start");
		try {
			ConcurrentSkipListMap<MachineInfo,NodeId> map = new ConcurrentSkipListMap<MachineInfo,NodeId>();
			Map<String, IDbMachine> dbMapMachines = getDbMapMachines();
			for(Entry<NodeId,MachineInfo> entry : unsortedMachines.entrySet()) {
				NodeId nodeId = entry.getKey();
				IDbMachine dbMachine = getDbMachine(dbMapMachines, nodeId);
				MachineInfo machineInfo = entry.getValue();
				determineStatus(machineInfo, dbMachine);
				map.put(machineInfo, nodeId);
				logger.debug(location, jobid, "put: "+nodeId);
			}
			setSortedMachines(map);
			updateMachineFactsList();
		}
		catch(Exception e) {
			logger.error(location, jobid, e);
		}
		logger.debug(location, jobid, "end");
	} 
	
	private volatile String published = null;
	
	private DuccMachinesData() {
		initialize();
	}
	
	private void initialize() {
		String location = "initialize";
		try {
			String fileName = IDuccEnv.DUCC_NODES_FILE_NAME;
			String dirResources = IDuccEnv.DUCC_RESOURCES_DIR;
			ArrayList<String> nodes =  DuccNodes.getInstance().get(dirResources,fileName);
			Iterator<String> iterator = nodes.iterator();
			while(iterator.hasNext()) {
				String nodeName = (String) iterator.next();
				String memTotal = "";
				String memFree = "";
				String swapInuse = "";
				String swapFree = "";
				double cpu = 0;
				MachineInfo machineInfo = new MachineInfo(IDuccEnv.DUCC_NODES_FILE_PATH, "", nodeName, memTotal, memFree, swapInuse, swapFree, cpu, false, null, -1, 0);
				putMachine(machineInfo);
			}
			updateSortedMachines();
		}
		catch(Throwable t) {
			logger.warn(location, jobid, t);
		}
	}
	
	// add or update machine info; remove corresponding "defined" entry, if it exists
	
	private void putMachine(MachineInfo machineInfo) {
		String location = "putMachine";
		try {
			if(machineInfo != null) {
				String name = machineInfo.getName();
				if(name != null) {
					String longName = name.trim();
					if(longName.length() > 0) {
						NodeId nodeId = new NodeId(longName);
						unsortedMachines.put(nodeId,machineInfo);
						logger.trace(location, jobid, "add="+nodeId.toString()+","+machineInfo.getIp());
						String shortName = longName.split("\\.")[0];
						if(!shortName.equals(longName)) {
							NodeId shortId = new NodeId(shortName);
							if(unsortedMachines.containsKey(shortId)) {
								unsortedMachines.remove(shortId);
								logger.trace(location, jobid, "del="+shortId.toString());
							}
						}
					}
				}
			}
		}
		catch(Exception e) {
			logger.error(location, jobid, e);
		}
	}
	
	public boolean isPublished() {
		return published != null;
	}
	
	public void setPublished() {
		published = TimeStamp.getCurrentMillis();
	}
	
	public MachineSummaryInfo getTotals() {
		MachineSummaryInfo totals = new MachineSummaryInfo();
		totals.memTotal = memTotal.get();
		totals.memFree = memFree.get();
		totals.swapInuse = swapInuse.get();
		totals.swapFree = swapFree.get();
		return totals;
	}
	
	private void updateTotals(NodeId nodeId, MachineSummaryInfo newInfo) {
		if(summaryMachines.containsKey(nodeId)) {
			MachineSummaryInfo oldInfo = summaryMachines.get(nodeId);
			summaryMachines.put(nodeId, newInfo);
			memTotal.addAndGet(newInfo.memTotal-oldInfo.memTotal);
			memFree.addAndGet(newInfo.memFree-oldInfo.memFree);
			swapInuse.addAndGet(newInfo.swapInuse-oldInfo.swapInuse);
			swapFree.addAndGet(newInfo.swapFree-oldInfo.swapFree);
		}
		else {
			summaryMachines.put(nodeId, newInfo);
			memTotal.addAndGet(newInfo.memTotal);
			memFree.addAndGet(newInfo.memFree);
			swapInuse.addAndGet(newInfo.swapInuse);
			swapFree.addAndGet(newInfo.swapFree);
		}
	}
	
	private double getCpuLoadAvg(Node node) {
		String location = "getCpuLoadAvg";
		double cpu = 0;
		try {
			if(node != null) {
				String load = node.getNodeMetrics().getNodeLoadAverage().getLoadAvg1();
				cpu = ConvertSafely.String2Double(load);
			}
		}
		catch(Exception e) {
			logger.debug(location, jobid, e);
		}
		return cpu;
	}
	
	/**
	 * 
	 * @param duccEvent
	 * @return true is new node or false if already known node
	 * 
	 * Put new or updated node metrics into map of Agent node metric reports
	 */
	public void put(DatedNodeMetricsUpdateDuccEvent duccEvent) {
		String location = "put";
		MachineSummaryInfo msi = new MachineSummaryInfo();
		NodeMetricsUpdateDuccEvent nodeMetrics = duccEvent.getNodeMetricsUpdateDuccEvent();
		Ip ip = new Ip(nodeMetrics.getNodeIdentity().getIp().trim());
		TreeMap<String, NodeUsersInfo> map = nodeMetrics.getNodeUsersMap();
		if(map != null) {
			String ipString = ip.toString();
			ipToNodeUsersInfoMap.put(ipString, map);
		}
		String machineName = nodeMetrics.getNodeIdentity().getName().trim();
		NodeId nodeId = new NodeId(machineName);
		ipToNameMap.put(ip,nodeId);
		nameToIpMap.put(nodeId,ip);
		// mem: total
		long nodeMemTotal = nodeMetrics.getNodeMemory().getMemTotal();
		logger.debug(location, jobid, "node: "+machineName+" "+"memTotal: "+nodeMemTotal);
		long lvalMemTotal = (long) ((1.0*nodeMemTotal)/(1024*1024)+0.5);
		msi.memTotal = lvalMemTotal;
		String memTotal = ""+lvalMemTotal/*+memUnits*/;
		// mem: free
		long nodeMemFree = nodeMetrics.getNodeMemory().getMemFree();
		logger.debug(location, jobid, "node: "+machineName+" "+"memFree: "+nodeMemFree);
		long lvalMemFree = (long) ((1.0*nodeMemFree)/(1024*1024)+0.0);  // do NOT round up!
		msi.memFree = lvalMemFree;
		String memFree = ""+lvalMemFree/*+memUnits*/;
		// swap: in-use
		double dvalSwapTotal = nodeMetrics.getNodeMemory().getSwapTotal();
		long lvalSwapTotal = (long) (dvalSwapTotal/(1024*1024)+0.5);
		double dvalSwapFree = nodeMetrics.getNodeMemory().getSwapFree();
		long lvalSwapFree = (long) (dvalSwapFree/(1024*1024)+0.5);
		long lvalSwapInuse = lvalSwapTotal - lvalSwapFree;
		String swapInuse = ""+lvalSwapInuse/*+memUnits*/;
		msi.swapInuse = lvalSwapInuse;
		String swapKey = ip.toString();
		String swapVal = swapInuse;
		if(msi.swapInuse > 0) {
			isSwapping.put(swapKey, swapVal);
		}
		else {
			isSwapping.remove(swapKey);
		}
		//String swapFree = ""+lval/*+memUnits*/;
		msi.swapFree = lvalSwapFree;
		String swapFree = ""+lvalSwapFree/*+memUnits*/;
		List<ProcessInfo> alienPids = nodeMetrics.getRogueProcessInfoList();
		Node node = nodeMetrics.getNode();
		double cpu = getCpuLoadAvg(node);
		boolean cGroups = nodeMetrics.getCgroups();
		MachineInfo current = new MachineInfo("", ip.toString(), machineName, memTotal, memFree, ""+swapInuse, ""+swapFree, cpu, cGroups, alienPids, duccEvent.getMillis(), duccEvent.getEventSize());
		
		NodeId key = nodeId;
		MachineInfo previous = unsortedMachines.get(key);
		if(previous != null) {
			try {
				long swapPrev = Long.parseLong(previous.getSwapInuse());
				long swapCurr = Long.parseLong(current.getSwapInuse());
				long swapDelta = swapCurr - swapPrev;
				current.setSwapDelta(swapDelta);;
			}
			catch(Exception e) {
			}
			long pHbMax = previous.getHeartbeatMax();
			long tod = previous.getHeartbeatMaxTOD();
			long pHbElapsed = previous.getElapsedSeconds();
			if(pHbElapsed > pHbMax) {
				pHbMax = pHbElapsed;
				tod = previous.getHeartbeat();
			}
			current.setHeartbeatMax(pHbMax);
			current.setHeartbeatMaxTOD(tod);
			long pubSizeMax = previous.getPubSizeMax();
			long pubSize = current.getPubSize();
			if(pubSize > pubSizeMax) {
				pubSizeMax = pubSize;
			}
			current.setPubSizeMax(pubSizeMax);
		}
		putMachine(current);
		updateTotals(nodeId,msi);
		setPublished();
	}
	
	public List<String> getPids(Ip ip, UserId user) {
		String location = "getPids";
		List<String> retVal = new ArrayList<String>();
		if(ip == null) {
		}
		else if(ip.toString() == null) {
		}
		else if(user == null) {
		}
		else if(user.toString() == null) {
		}
		else {
			try {
				TreeMap<String, NodeUsersInfo> map = ipToNodeUsersInfoMap.get(ip.toString());
				if(map != null) {
					NodeUsersInfo nodeUsersInfo = map.get(user.toString());
					if(nodeUsersInfo != null) {
						for( NodeProcess process : nodeUsersInfo.getReserveProcesses() ) {
							retVal.add(process.getPid());
						}
//						retVal = nodeUsersInfo.getPids();
					}
				}
			}
			catch(Exception e) {
				logger.error(location, jobid, e);
			}
		}
		return retVal;
	}
	
	public List<String> getPids(NodeId nodeId, UserId user) {
		Ip ip = new Ip(getIpForName(nodeId.toString()));
		return getPids(ip, user);
	}
	
	public List<NodePidList> getUserProcesses(List<String> nodeList, String user) {
		List<NodePidList> nodePidListList = new ArrayList<NodePidList>();
		for(String node : nodeList) {
			List<String> pids = getPids(new NodeId(node), new UserId(user));
			NodePidList nodePidList = new NodePidList(node, pids);
			nodePidListList.add(nodePidList);
		}
		return nodePidListList;
	}
	
	public int getPidCount(Ip ip, UserId user) {
		int retVal = 0;
		try {
			List<String> pidList = getPids(ip, user);
			if(pidList != null) {
				return pidList.size();
			}
		}
		catch(Exception e) {
			retVal = -1;
		}
		return retVal;
	}
	
	public int getPidCount(NodeId nodeId, UserId user) {
		Ip ip = new Ip(getIpForName(nodeId.toString()));
		return getPidCount(ip, user);
	}
	
	public String getNameForIp(String ipString) {
		String retVal = null;
		try {
			Ip ip = new Ip(ipString);
			NodeId nodeId = ipToNameMap.get(ip);
			if(nodeId != null) {
				retVal = nodeId.toString();
			}
		}
		catch(Throwable t) {
		}
		return retVal;
	}
	
	public String getIpForName(String name) {
		String retVal = null;
		try {
			NodeId nodeId = new NodeId(name);
			Ip ip = nameToIpMap.get(nodeId);
			if(ip != null) {
				retVal = ip.toString();
			}
		}
		catch(Throwable t) {
		}
		return retVal;
	}
	
	/**
	 * Create a cached data set employed by the WS 
	 * to display the System -> Machines page.  The
	 * code is dual-pathed, depending on whether or
	 * not the system is configured to use database.
	 */
	private void updateMachineFactsList() {
		String location = "updateMachineFactsList";
		try {
			DbQuery dbQuery = DbQuery.getInstance();
			if(!dbQuery.isEnabled()) {
				updateMachineFactsListAgent();
			}
			else {
				updateMachineFactsListDb();
			}
		}
		catch(Exception e) {
			logger.error(location, jobid, e);
			System.out.println(e.getMessage());
		}
	}
	
	
	
	/**
	 * Adjust memory value by rounding down 
	 * to multiple of rm.share.quantum GB
	 */
	private String calculateMem(long quantum, String memParm) {
		String location = "calculateMem";
		String retVal = "0";
		if(memParm!= null) {
			String memString = memParm.trim();
			if(memString.length() > 0) {
				try {
					long memRaw = Long.parseLong(memString);
					long memAdj = (memRaw / quantum) * quantum;
					retVal = ""+memAdj;
				}
				catch(Exception e) {
					logger.error(location, jobid, e);
				}
			}
		}
		return retVal;
	}
	
	/**
	 * Fetch quantum from ducc.properties, default is 1.
	 */
	private long getQuantum() {
		String location = "getQuantum";
		long retVal = 1;
		try {
			DuccPropertiesResolver dpr = DuccPropertiesResolver.getInstance();
			String quantum = dpr.getFileProperty(DuccPropertiesResolver.ducc_rm_share_quantum);
			retVal = Long.parseLong(quantum.trim());
		}
		catch(Exception e) {
			logger.error(location, jobid, e);
		}
		return retVal;
	}
	
	/**
	 * Create a machines facts list based 
	 * in part on the information provided by the Agents, and
	 * in part on the data comprising the ducc.nodes file.
	 */
	private void updateMachineFactsListAgent() {
		MachineFactsList factsList = new MachineFactsList();
		long quantum = getQuantum();
		Map<MachineInfo,NodeId> sortedMachines = getSortedMachines();
		Iterator<MachineInfo> iterator;
		iterator = sortedMachines.keySet().iterator();
		while(iterator.hasNext()) {
			MachineInfo machineInfo = iterator.next();
			MachineStatus machineStatus = machineInfo.getMachineStatus();
			String status = machineStatus.getLowerCaseName();
			String statusReason = "";
			String ip = machineInfo.getIp();
			String name = machineInfo.getName();
			String memTotal = calculateMem(quantum, machineInfo.getMemTotal());
			String memFree = calculateMem(quantum, machineInfo.getMemFree());
			String swapInuse = machineInfo.getSwapInuse();
			String swapDelta = ""+machineInfo.getSwapDelta();
			String swapFree = machineInfo.getSwapFree();
			double cpu = machineInfo.getCpu();
			boolean cGroups = machineInfo.getCgroups();
			List<String> aliens = machineInfo.getAliens();
			String heartbeat = ""+machineInfo.getElapsed();
			MachineFacts facts = new MachineFacts(status,statusReason,ip,name,memTotal,memFree,swapInuse,swapDelta,swapFree,cpu,cGroups,aliens,heartbeat);
			// when not using DB, memResrve == memTotal
			facts.memReserve = memTotal;
			factsList.add(facts);
		}
		machineFactsList = factsList;
	}
	
	/**
	 * Create a machines facts list based 
	 * in part on the entries in the RM-maintained database, and
	 * in part on the information provided by the Agents, and
	 * in part on the data comprising the ducc.nodes file.
	 */
	private void updateMachineFactsListDb() {
		String location = "updateMachineFactsListDb";
		// The returnable
		MachineFactsList mfl = new MachineFactsList();
		// Working map used to generate the returnable
		Map<MachineInfo,NodeId> dbSortedMachines = new TreeMap<MachineInfo,NodeId>();
		// Get map from DB courtesy of RM
		DbQuery dbQuery = DbQuery.getInstance();
		// Working list of known machines, by long name
		Map<String, IDbMachine> dbMapMachinesLong = dbQuery.getMapMachines();
		// Working list of known machines, by short name
		Map<String, IDbMachine> dbMapMachinesShort = new HashMap<String, IDbMachine>();
		// Update working map and map of short names
		for(Entry<String, IDbMachine> entry : dbMapMachinesLong.entrySet()) {
			String name = entry.getKey();
			NodeId nodeId = new NodeId(name);
			dbMapMachinesShort.put(nodeId.getShortName(),entry.getValue());
			MachineInfo mi = unsortedMachines.get(nodeId);
			IDbMachine dbMachine = entry.getValue();
			if(mi != null) {
				int quantum = dbMachine.getQuantum();
				int total = quantum*dbMachine.getShareOrder();
				int free = quantum*dbMachine.getSharesLeft();
				mi.setMemTotal(""+total);
				mi.setMemFree(""+free);
				dbSortedMachines.put(mi, nodeId);
			}
		}
		// Initialize returnable with "defined" machines
		ArrayList<String> duccNodes = DuccNodes.getInstance().get();
		Map<String,String> sortedDuccNodes = new TreeMap<String,String>();
		for(String name : duccNodes) {
			NodeId nodeId = new NodeId(name);
			sortedDuccNodes.put(nodeId.getShortName(),nodeId.getLongName());
		}
		// Process defined nodes, unless already present from DB
		for(Entry<String, String> entry : sortedDuccNodes.entrySet()) {
			String shortName = entry.getKey();
			String longName = entry.getValue();
			// Skip defined machine if it already appears in DB
			if(dbMapMachinesShort.containsKey(shortName)) {
				continue;
			}
			if(dbMapMachinesLong.containsKey(longName)) {
				continue;
			}
			// Add defined machine
			String status = "defined";
			String statusReason = "";
			String ip = "";
			String memTotal = "";
			String memFree = "";
			String swapInuse = "";
			String swapDelta = "";
			String swapFree = "";
			double cpu = 0;
			boolean cGroups = false;
			List<String> aliens = new ArrayList<String>();
			String heartbeat = "";
			MachineFacts facts = new MachineFacts(status,statusReason,ip,longName,memTotal,memFree,swapInuse,swapDelta,swapFree,cpu,cGroups,aliens,heartbeat);
			mfl.add(facts);
		}
		// Augment returnable with data from Agents & RM (from DB)
		for(Entry<MachineInfo, NodeId> entry : dbSortedMachines.entrySet()) {
			MachineInfo machineInfo = entry.getKey();
			MachineStatus machineStatus = machineInfo.getMachineStatus();
			String status = machineStatus.getLowerCaseName();
			String statusReason = machineInfo.getMachineStatusReason();
			String ip = machineInfo.getIp();
			String name = machineInfo.getName();
			String memTotal = machineInfo.getMemTotal();
			String memFree = machineInfo.getMemFree();
			String swapInuse = machineInfo.getSwapInuse();
			String swapDelta = ""+machineInfo.getSwapDelta();
			String swapFree = machineInfo.getSwapFree();
			double cpu = machineInfo.getCpu();
			boolean cGroups = machineInfo.getCgroups();
			List<String> aliens = machineInfo.getAliens();
			String heartbeat = ""+machineInfo.getElapsed();
			MachineFacts facts = new MachineFacts(status,statusReason,ip,name,memTotal,memFree,swapInuse,swapDelta,swapFree,cpu,cGroups,aliens,heartbeat);
			facts.memReserve = machineInfo.getMemTotal();
			facts.quantum = ""+machineInfo.getQuantum();
			logger.trace(location, jobid, facts.status+" "+facts.statusReason);
			mfl.add(facts);
		}
		machineFactsList = mfl;
	}
	
	public MachineFactsList getMachineFactsList() {
		return machineFactsList;
	}
	
}
