/*******************************************************************************
 * Copyright (c) 2019 Dortmund University of Applied Sciences and Arts.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     FH Dortmund - initial API and implementation
 *******************************************************************************/
package org.eclipse.app4mc.gsoc_rta;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
import org.eclipse.app4mc.amalthea.model.Event;
import org.eclipse.app4mc.amalthea.model.EventChain;
import org.eclipse.app4mc.amalthea.model.EventChainContainer;
import org.eclipse.app4mc.amalthea.model.EventChainItem;
import org.eclipse.app4mc.amalthea.model.Label;
import org.eclipse.app4mc.amalthea.model.ProcessEvent;
import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
import org.eclipse.app4mc.amalthea.model.Task;
import org.eclipse.app4mc.amalthea.model.Time;
import org.eclipse.app4mc.amalthea.model.TimeUnit;
import org.eclipse.app4mc.amalthea.model.io.AmaltheaLoader;
import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
import org.eclipse.app4mc.amalthea.model.util.SoftwareUtil;
import org.eclipse.app4mc.gsoc_rta.SharedConsts.ComParadigm;
import org.eclipse.emf.common.util.EList;

/**
 * Date: August 21-2019
 * @author Junhyung Ki
 * @version 1.0
 * 				This class is to analyze End-to-End latency with the help of CPURta class.
 */
public class E2ELatency {
	public CPURta cpurta = new CPURta();
	public static final int[] defaultIAMapping = new int[] { 4, 1, 1, 3, 4, 0, 3, 3, 3, 0, 6, 2, 5, 6 };
	public static void main(String[] args) {
		org.apache.log4j.BasicConfigurator.configure();
		Logger.getRootLogger().setLevel(Level.ERROR);
		final E2ELatency ecl = new E2ELatency();
		ecl.run();
	}
	
	public void run() {
		final Logger log = Logger.getLogger(E2ELatency.class);
		this.setCPURta(this.cpurta);
		final EList<EventChain> ecList = this.cpurta.getModel().getConstraintsModel().getEventChains();
		for (int i = 0; i < ecList.size(); i++) {
			log.debug(" ----- " + "Chain " + (i+1) + " ----- ");
			log.debug("Best-case Task-Chain Reaction(Direct): " + this.getTCReactionBC(ecList.get(i), ComParadigm.DIRECT, this.cpurta));
			log.debug("Worst-case Task-Chain Reaction(Direct): " + this.getTCReactionWC(ecList.get(i), ComParadigm.DIRECT, this.cpurta));
			log.debug("Best-case Task-Chain Reaction(Implicit): " + this.getTCReactionBC(ecList.get(i), ComParadigm.IMPLICIT, this.cpurta));
			log.debug("Worst-case Task-Chain Reaction(Implicit): " + this.getTCReactionWC(ecList.get(i), ComParadigm.IMPLICIT, this.cpurta));
			log.debug("Best-case Task-Chain Reaction(LET): " + this.getLetReactionBC(ecList.get(i), this.cpurta));
			log.debug("Worst-case Task-Chain Reaction(LET): " + this.getLetReactionWC(ecList.get(i), this.cpurta));
			log.debug("Worst-case Task-Chain Age(Direct): " + this.getTaskChainAge(ecList.get(i), TimeType.WCET, ComParadigm.DIRECT, this.cpurta));
			log.debug("Best-case Task-Chain Age(Direct): " + this.getTaskChainAge(ecList.get(i), TimeType.BCET, ComParadigm.DIRECT, this.cpurta));
			log.debug("Worst-case Task-Chain Age(Implicit): " + this.getTaskChainAge(ecList.get(i), TimeType.WCET, ComParadigm.IMPLICIT, this.cpurta));
			log.debug("Best-case Task-Chain Age(Implicit): " + this.getTaskChainAge(ecList.get(i), TimeType.BCET, ComParadigm.IMPLICIT, this.cpurta));
			log.debug("Worst-case Early Reaction(Direct): " + this.getEarlyReaction(ecList.get(i), TimeType.WCET, ComParadigm.DIRECT, this.cpurta));
			log.debug("Best-case Early Reaction(Direct): " + this.getEarlyReaction(ecList.get(i), TimeType.BCET, ComParadigm.DIRECT, this.cpurta));
			log.debug("Worst-case Early Reaction(Implicit): " + this.getEarlyReaction(ecList.get(i), TimeType.WCET, ComParadigm.IMPLICIT, this.cpurta));
			log.debug("Best-case Early Reaction(Implicit): " + this.getEarlyReaction(ecList.get(i), TimeType.BCET, ComParadigm.IMPLICIT, this.cpurta));
			log.debug("\n");
		}
		log.debug("\n################################################################################################################\n");
		for (int i = 0; i < ecList.size(); i++) {
			log.debug(" ----- " + "Chain " + (i+1) + " ----- ");
			for (int j = 0; j < this.cpurta.getModel().getSwModel().getLabels().size(); j++) {
				final Label label = this.cpurta.getModel().getSwModel().getLabels().get(j);
				log.debug("***** " + label.getName() + " *****");
				log.debug("Worst-case Data Age(Direct): " + this.getDataAge(label, ecList.get(i), TimeType.WCET, ComParadigm.DIRECT, this.cpurta));
				log.debug("Best-case Data Age(Direct): " + this.getDataAge(label, ecList.get(i), TimeType.BCET, ComParadigm.DIRECT, this.cpurta));
				log.debug("Worst-case Data Age(Implicit): " + this.getDataAge(label, ecList.get(i), TimeType.WCET, ComParadigm.IMPLICIT, this.cpurta));
				log.debug("Best-case Data Age(Implicit): " + this.getDataAge(label, ecList.get(i), TimeType.BCET, ComParadigm.IMPLICIT, this.cpurta) + "\n");
			}
			log.debug("\n");
		}
	}
	
	/**
	 * Set CPURta class
	 * @param cpurta		the instance of CPURta class
	 */
	public void setCPURta(final CPURta cpurta) {
		final Logger log = Logger.getLogger(E2ELatency.class);
		cpurta.setModel(AmaltheaLoader.loadFromFile(cpurta.inputFile));
		if (cpurta.getModel() == null) {
			log.debug("NOT GOOD!");
		}
		cpurta.setTRT(cpurta.getDefaultTRT(cpurta.getModel()));
		cpurta.setIA(defaultIAMapping);
		cpurta.setPUl(CommonUtils.getPUs(cpurta.getModel()));
		cpurta.setContention(cpurta.getIA(), cpurta.getModel());
	}
	
	/**
	 * Check the readiness of the observed class instance
	 * @param cpurta		the instance of CPURta class
	 * @return
	 * 				boolean value that indicates whether cpurta instance is ready
	 */
	private boolean isTheRTAClassReady(final CPURta cpurta) {
		final Logger log = Logger.getLogger(E2ELatency.class);
		if (cpurta.getModel() == null) {
			log.debug("Model Setting needs to be done for cpurta!");
			return false;
		} else if (cpurta.getTRT() == null) {
			log.debug("TRT Setting needs to be done for cpurta!");
			return false;
		} else if (cpurta.getIA() == null) {
			log.debug("IA Setting needs to be done for cpurta!");
			return false;
		} else if (cpurta.getPUl().size() == 0) {
			log.debug("PUl Setting needs to be done for cpurta!");
			return false;
		} else if (cpurta.getCT() == null) {
			log.debug("CT Setting needs to be done for cpurta!");
			return false;
		}
		return true;
	}
	
	/**
	 * Reaction: The time between one of the chain's first task instances to the earliest one of the chain's last task instances 
	 * which are propagated from the initial one. (which we can also call the best-case task-chain age latency) 
	 * the best-case E2E Chain Reaction(Direct or Implicit) = Sum of all entities' BCRT
	 * @param ec			the observed event chain
	 * @param paradigm		communication paradigm (DIRECT, IMPLICIT)
	 * @param cpurta		the instance of CPURta class
	 * @return
	 * 				the best-case E2E Chain Reaction(Direct or Implicit)
	 */
	public Time getTCReactionBC(final EventChain ec, final ComParadigm paradigm, final CPURta cpurta) {
		final Logger log = Logger.getLogger(E2ELatency.class);
		Time e2eRctImplicit = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
		if (isTheRTAClassReady(cpurta)) {
			final List<Task> taskChain = getECTaskList(ec);
			if (taskChain.size() == 0) {
				log.error("This task chain is empty.");
				return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			}
			for (int i = 0; i < taskChain.size(); i++) {
				final Task task = taskChain.get(i);
				final ProcessingUnit pu = getPU(task, cpurta);
				final List<Task> taskList = getSortedTaskList(task, pu, cpurta);
				Time bcrt = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				if (isMappedToCPU(task, cpurta)) {
					if (paradigm.equals(ComParadigm.DIRECT)) {
						bcrt = cpurta.preciseTestCPURT(task, taskList, TimeType.BCET, pu);
					} else if (paradigm.equals(ComParadigm.IMPLICIT)) {
						bcrt = cpurta.implicitPreciseTest(task, taskList, TimeType.BCET, pu, cpurta);
					} else {
						log.error("'COM_PARADIGM == null' does not work.");
						return null;
					}
				} else {
					bcrt = cpurta.getTRT().get(task);
				}
				/* The task is not schedulable */
				final BigInteger biPeriod = AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(task));
				if (AmaltheaServices.convertToPicoSeconds(bcrt).compareTo(biPeriod) > 0) {
					return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				}
				e2eRctImplicit = e2eRctImplicit.add(bcrt);
			}
			return e2eRctImplicit;
		}
		log.error("cpurta instance is not ready!");
		return null;
	}

	/**
	 * The worst case task chain reaction latency for Direct or Implicit Communication
	 * @param ec			the observed event chain
	 * @param paradigm		communication paradigm (DIRECT, IMPLICIT)
	 * @param cpurta		the instance of CPURta class
	 * @return
	 * 				the worst-case E2E Chain Reaction(Direct or Implicit)
	 */
	public Time getTCReactionWC(final EventChain ec, final ComParadigm paradigm, final CPURta cpurta) {
		final Logger log = Logger.getLogger(E2ELatency.class);
		Time e2eRctWC = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
		if (isTheRTAClassReady(cpurta)) {
			final List<Task> taskChain = getECTaskList(ec);
			if (taskChain.size() == 0) {
				log.error("This task chain is empty.");
				return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			}
			for (int i = 0; i < taskChain.size() - 1; i++) {
				final Task task = taskChain.get(i);
				final Time period = CommonUtils.getStimInTime(task);
				e2eRctWC = e2eRctWC.add(period.multiply(2));
			}
			final Task task = taskChain.get(taskChain.size() - 1);
			Time wcrt = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			if (isMappedToCPU(task, cpurta)) {
				final ProcessingUnit pu = getPU(task, cpurta);
				final List<Task> taskList = getSortedTaskList(task, pu, cpurta);
				if (paradigm.equals(ComParadigm.DIRECT)) {
					wcrt = cpurta.preciseTestCPURT(task, taskList, TimeType.WCET, pu);
				} else if (paradigm.equals(ComParadigm.IMPLICIT)) {
					wcrt = cpurta.implicitPreciseTest(task, taskList, TimeType.WCET, pu, cpurta);
				} else {
					log.error("'COM_PARADIGM == null' does not work.");
					return null;
				}
			} else {
				wcrt = cpurta.getTRT().get(task);
			}
			/* The task is not schedulable */
			final BigInteger biPeriod = AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(task));
			if (AmaltheaServices.convertToPicoSeconds(wcrt).compareTo(biPeriod) > 0) {
				return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			}
			e2eRctWC = e2eRctWC.add(wcrt);
			return e2eRctWC;
		}
		log.error("cpurta instance is not ready!");
		return null;
	}
	
	/**
	 * Reaction: The time between one of the chain's first task instances to the earliest one of the chain's last task instances 
	 * which are propagated from the initial one. (which we can also call the best-case task-chain age latency)
	 * the best-case E2E Chain Reaction(LET) = Sum of all entities' periods
	 * @param ec			the observed event chain
	 * @param cpurta		the instance of CPURta class
	 * @return
	 * 				the best-case E2E Chain Reaction(LET)
	 */
	public Time getLetReactionBC(final EventChain ec, final CPURta cpurta) {
		final Logger log = Logger.getLogger(E2ELatency.class);
		Time e2eRctLET = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
		if (isTheRTAClassReady(cpurta)) {
			final List<Task> taskChain = getECTaskList(ec);
			if (taskChain.size() == 0) {
				log.error("This task chain is empty.");
				return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			}
			for (int i = 0; i < taskChain.size(); i++) {
				final Task task = taskChain.get(i);
				e2eRctLET = e2eRctLET.add(CommonUtils.getStimInTime(task));
			}
			return e2eRctLET;
		}
		log.error("cpurta instance is not ready!");
		return null;
	}
	
	/**
	 * The worst case task chain reaction latency for LET Communication
	 * @param ec			the observed event chain
	 * @param cpurta		the instance of CPURta class
	 * @return
	 * 				the worst-case E2E Chain Reaction(LET)
	 */
	public Time getLetReactionWC(final EventChain ec, final CPURta cpurta) {
		final Logger log = Logger.getLogger(E2ELatency.class);
		Time e2eRctWC = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
		if (isTheRTAClassReady(cpurta)) {
			final List<Task> taskChain = getECTaskList(ec);
			if (taskChain.size() == 0) {
				log.error("This task chain is empty.");
				return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			}
			final Task task0 = taskChain.get(0);
			final Time period0 = CommonUtils.getStimInTime(task0);
			e2eRctWC = e2eRctWC.add(period0);
			for (int i = 1; i < taskChain.size(); i++) {
				final Task task = taskChain.get(i);
				final Time period = CommonUtils.getStimInTime(task);
				e2eRctWC = e2eRctWC.add(period.multiply(2));
			}
			return e2eRctWC;
		}
		log.error("cpurta instance is not ready!");
		return null;
	}
	
	/**
	 * A task chain age latency equals the chain's last (response) task age latency
	 * worst-case: period - bcrt + wcrt
	 * best-case: period - wcrt + bcrt
	 * @param ec				the observed event chain
	 * @param executionCase		WCET / BCET
	 * @param paradigm			communication paradigm (DIRECT, IMPLICIT)
	 * @param cpurta			the instance of CPURta class
	 * @return
	 * 				the worst-case E2E Task-Chain Age
	 */
	public Time getTaskChainAge(final EventChain ec, final TimeType executionCase, final ComParadigm paradigm, final CPURta cpurta) {
		final Logger log = Logger.getLogger(E2ELatency.class);
		Time e2eTCAgeWC = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
		if (isTheRTAClassReady(cpurta)) {
			final List<Task> taskChain = getECTaskList(ec);
			if (taskChain.size() == 0) {
				log.error("This task chain is empty.");
				return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			}
			final Task task = taskChain.get(taskChain.size()-1);
			if (isMappedToCPU(task, cpurta)) {
				final Time period = CommonUtils.getStimInTime(task);
				final ProcessingUnit pu = getPU(task, cpurta);
				final List<Task> taskList = getSortedTaskList(task, pu, cpurta);
				Time bcrt = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				Time wcrt = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				if (paradigm.equals(ComParadigm.DIRECT)) {
					bcrt = cpurta.preciseTestCPURT(task, taskList, TimeType.BCET, pu);
					wcrt = cpurta.preciseTestCPURT(task, taskList, TimeType.WCET, pu);
				} else if (paradigm.equals(ComParadigm.IMPLICIT)) {
					bcrt = cpurta.implicitPreciseTest(task, taskList, TimeType.BCET, pu, cpurta);
					wcrt = cpurta.implicitPreciseTest(task, taskList, TimeType.WCET, pu, cpurta);
				} else {
					log.error("'COM_PARADIGM == null' does not work.");
					return null;
				}
				/* The task is not schedulable */
				final BigInteger biPeriod = AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(task));
				if (AmaltheaServices.convertToPicoSeconds(bcrt).compareTo(biPeriod) > 0) {
					return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				} else if (AmaltheaServices.convertToPicoSeconds(wcrt).compareTo(biPeriod) > 0) {
					return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				}
				if (executionCase.equals(TimeType.WCET)) {
					e2eTCAgeWC = period.subtract(bcrt).add(wcrt);
				} else if (executionCase.equals(TimeType.BCET)) {
					e2eTCAgeWC = period.subtract(wcrt).add(bcrt);
				} else {
					log.error("Only WCET or BCET is allowed!");
					return null;
				}
			} else {
				// TODO: if the observed task is mapped to GPU, then how should we calculate wcrt, bcrt?
				log.debug("GPU Task, how should we calculate wcrt, bcrt?");
			}
			return e2eTCAgeWC;
		}
		log.error("cpurta instance is not ready!");
		return null;
	}

	/**
	 * The method is to be used for calculating 'reaction update'.
	 * @param ec				the observed event chain
	 * @param executionCase		WCET / BCET
	 * @param paradigm			communication paradigm (DIRECT, IMPLICIT)
	 * @param cpurta			the instance of CPURta class
	 * @return
	 * 				the reaction latency value of the observed event chain
	 */
	public Time getEarlyReaction(final EventChain ec, final TimeType executionCase, final ComParadigm paradigm, final CPURta cpurta) {
		final Logger log = Logger.getLogger(E2ELatency.class);
		Time e2eEarlyRct = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
		if (isTheRTAClassReady(cpurta)) {
			final List<Task> taskChain = getECTaskList(ec);
			if (taskChain.size() == 0) {
				log.error("This task chain is empty.");
				return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			}
			final Task task0 = taskChain.get(0);
			Time rt0 = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			if (isMappedToCPU(task0, cpurta)) {
				final ProcessingUnit pu = getPU(task0, cpurta);
				final List<Task> taskList = getSortedTaskList(task0, pu, cpurta);
				if (paradigm.equals(ComParadigm.DIRECT)) {
					rt0 = cpurta.preciseTestCPURT(task0, taskList, executionCase, pu);
				} else if (paradigm.equals(ComParadigm.IMPLICIT)) {
					rt0 = cpurta.implicitPreciseTest(task0, taskList, executionCase, pu, cpurta);
				} else {
					log.error("'COM_PARADIGM == null' does not work.");
					return null;
				}
			} else {
				rt0 = cpurta.getTRT().get(task0);
			}
			/* The task is not schedulable */
			final BigInteger biPeriod0 = AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(task0));
			if (AmaltheaServices.convertToPicoSeconds(rt0).compareTo(biPeriod0) > 0) {
				return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			}
			e2eEarlyRct = e2eEarlyRct.add(rt0);
			Time epsilon = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			for (int i = 0; i < taskChain.size() - 1; i++) {
				final Time nextPeriod = CommonUtils.getStimInTime(taskChain.get(i + 1));
				/* SUM (Sigma Starts) */
				final Time period = CommonUtils.getStimInTime(taskChain.get(i));
				final Task currentTask = taskChain.get(i);
				Time rtA = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				if (isMappedToCPU(currentTask, cpurta)) {
					final ProcessingUnit puA = getPU(currentTask, cpurta);
					final List<Task> taskListA = getSortedTaskList(currentTask, puA, cpurta);
					/* NOTE: Sometimes rtA, rtB are BigInteger.valueOf(Long.MAX_VALUE) if it is executed with the implicit communication paradigm */
					/* In that case, the task is not schedulable, so the method should return 0 ps, otherwise the result is not correct and
					 * would likely be negative (subtract the max BigIntegerValue would be obviously negative in most cases) */
					if (paradigm.equals(ComParadigm.DIRECT)) {
						rtA = cpurta.preciseTestCPURT(currentTask, taskListA, executionCase, puA);
					} else if (paradigm.equals(ComParadigm.IMPLICIT)) {
						rtA = cpurta.implicitPreciseTest(currentTask, taskListA, executionCase, puA, cpurta);
					}
				} else {
					rtA = cpurta.getTRT().get(currentTask);
				}
				/* The task is not schedulable */
				final BigInteger biPeriod = AmaltheaServices.convertToPicoSeconds(period);
				if (AmaltheaServices.convertToPicoSeconds(rtA).compareTo(biPeriod) > 0) {
					return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				}
				final Time currentEpsilon = (((period.multiply(2)).subtract(rtA)).subtract(nextPeriod)).subtract(epsilon);
				epsilon = currentEpsilon;
				final Task nextTask = taskChain.get(i + 1);
				Time rtB = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				if (isMappedToCPU(nextTask, cpurta)) {
					final ProcessingUnit puB = getPU(nextTask, cpurta);
					final List<Task> taskListB = getSortedTaskList(nextTask, puB, cpurta);
					if (paradigm.equals(ComParadigm.DIRECT)) {
						rtB = cpurta.preciseTestCPURT(nextTask, taskListB, executionCase, puB);
					} else if (paradigm.equals(ComParadigm.IMPLICIT)) {
						rtB = cpurta.implicitPreciseTest(nextTask, taskListB, executionCase, puB, cpurta);
					}
				} else {
					rtB = cpurta.getTRT().get(nextTask);
				}
				/* The task is not schedulable */
				final BigInteger biPeriodB = AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(nextTask));
				if (AmaltheaServices.convertToPicoSeconds(rtB).compareTo(biPeriodB) > 0) {
					return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				}
				if (nextPeriod.compareTo(currentEpsilon.add(rtB)) < 0) {
					e2eEarlyRct = e2eEarlyRct.add(nextPeriod.multiply(2));
				} else {
					e2eEarlyRct = e2eEarlyRct.add(nextPeriod.add(currentEpsilon.add(rtB)));
				}
				if (e2eEarlyRct.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) < 0) {
					return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
				}
			}
			return e2eEarlyRct;
		}
		log.error("cpurta instance is not ready!");
		return null;
	}
	
	/**
	 * the longest time some data version persists in memory.
	 * worst-case: min (worst-case age latencies of the tasks that contain the observed label)
	 * best-case: min (best-case age latencies of the tasks that contain the observed label)
	 * @param label				the observed label (data)
	 * @param ec				the observed event-chain
	 * @param executionCase		WCET / BCET
	 * @param paradigm			communication paradigm (DIRECT, IMPLICIT)
	 * @param cpurta			the instance of CPURta class
	 * @return
	 * 				the data age latency (wc or bc) of the given label
	 * 				If any of tasks in the chain does not contain the observed label, the method shall return null.
	 */
	public Time getDataAge(final Label label, final EventChain ec, final TimeType executionCase, final ComParadigm paradigm, final CPURta cpurta) {
		final Logger log = Logger.getLogger(E2ELatency.class);
		if (isTheRTAClassReady(cpurta)) {
			final List<Time> dataAgeList = new ArrayList<Time>();
			final List<Task> taskChain = getECTaskList(ec);
			if (taskChain.size() == 0) {
				log.error("This task chain is empty.");
				return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
			}
			for (int i = 0; i < taskChain.size(); i++) {
				if (isMappedToCPU(taskChain.get(i), cpurta)) {
					final Task task = taskChain.get(i);
					final Set<Label> labelSet = SoftwareUtil.getAccessedLabelSet(task, null);
					if(labelSet.contains(label)) {
						Time dataAge = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
						final ProcessingUnit pu = getPU(task, cpurta);
						final List<Task> taskList = getSortedTaskList(task, pu, cpurta);
						final Time period = CommonUtils.getStimInTime(task);
						Time bcrt = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
						Time wcrt = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
						if (paradigm.equals(ComParadigm.DIRECT)) {
							bcrt = cpurta.preciseTestCPURT(task, taskList, TimeType.BCET, pu);
							wcrt = cpurta.preciseTestCPURT(task, taskList, TimeType.WCET, pu);
						} else if (paradigm.equals(ComParadigm.IMPLICIT)) {
							bcrt = cpurta.implicitPreciseTest(task, taskList, TimeType.BCET, pu, cpurta);
							wcrt = cpurta.implicitPreciseTest(task, taskList, TimeType.WCET, pu, cpurta);
						} else {
							log.error("'COM_PARADIGM == null' does not work.");
							return null;
						}
						/* The task is not schedulable */
						final BigInteger biPeriod = AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(task));
						if (AmaltheaServices.convertToPicoSeconds(bcrt).compareTo(biPeriod) > 0) {
							return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
						} else if (AmaltheaServices.convertToPicoSeconds(wcrt).compareTo(biPeriod) > 0) {
							return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
						}
						if (executionCase.equals(TimeType.WCET)) {
							dataAge = period.subtract(bcrt).add(wcrt);
						} else if (executionCase.equals(TimeType.BCET)) {
							dataAge = period.subtract(wcrt).add(bcrt);
						} else {
							log.error("Only WCET or BCET is allowed!");
						}
						dataAgeList.add(dataAge);
					}
				}
			}
			if (dataAgeList.size() != 0) {
				Collections.sort(dataAgeList, new TimeComp());
				return dataAgeList.get(0);
			}
			return null;
		}
		log.error("cpurta instance is not ready!");
		return null;
	}
	
	/**
	 * Get an Event-Chain Entity List (Task-based)
	 * @param ec			the observed event chain
	 * @return			
	 * 				the corresponding EC task list
	 */
	public List<Task> getECTaskList(final EventChain ec) {
		final List<Task> chain = new ArrayList<Task>();
		for (int i = 0; i < ec.getSegments().size(); i++) {
			final EventChainItem eci = ec.getSegments().get(i);
			if (eci instanceof EventChainContainer) {
				final EventChainContainer ecc = (EventChainContainer) eci;
				final Event stiEvent = ecc.getEventChain().getStimulus();
				if (stiEvent instanceof ProcessEvent) {
					final Task stiTask = (Task)((ProcessEvent) stiEvent).getEntity();
					chain.add(stiTask);
				}
				if (i == ec.getSegments().size() - 1) {
					final Event resEvent = ecc.getEventChain().getResponse();
					if (resEvent instanceof ProcessEvent) {
						final Task resTask = (Task)((ProcessEvent) resEvent).getEntity();
						chain.add(resTask);
					}
					break;
				}
			}
		}
		return chain;
	}
	
	/**
	 * get the processing unit that the observed task is mapped to
	 * @param task			the observed task
	 * @param cpurta		the instance of CPURta class
	 * @return
	 * 				pu
	 */
	private ProcessingUnit getPU(final Task task, final CPURta cpurta) {
		final int tindex = cpurta.getModel().getSwModel().getTasks().indexOf(task);
		final int puindex = cpurta.getIA()[tindex];
		final ProcessingUnit pu = cpurta.getPUl().get(puindex);
		return pu;
	}
	
	/**
	 * get the sorted task listed based on the given integer array mapping
	 * @param task			the observed task
	 * @param pu			ProcessingUnit that would compute the given method
	 * @param cpurta		the instance of CPURta class
	 * @return
	 * 				sortedTaskList
	 */
	private List<Task> getSortedTaskList(final Task task, final ProcessingUnit pu, final CPURta cpurta) {
		final int puIndex = cpurta.getPUl().indexOf(pu);
		/* 2. get all tasks mapped to this CPU */
		final List<Task> puTaskList = new ArrayList<Task>();
		for (int i = 0; i < cpurta.getIA().length; i++) {
			if (cpurta.getIA()[i] == puIndex) {
				puTaskList.add(cpurta.getModel().getSwModel().getTasks().get(i));
			}
		}
		final List<Task> sortedTaskList = taskSorting(puTaskList);
		return sortedTaskList;
	}
	
	/**
	 * Sort out the given list of tasks (in order of shorter period first - Rate Monotonic Scheduling)
	 * @param taskList		list of tasks that is mapped to the same core	
	 * @return
	 * 				the sorted list of tasks
	 */
	private List<Task> taskSorting(final List<Task> taskList) {
		/* Getting stimuliList out of the given taskList (because it is RMS) */
		final List<Time> stimuliList = new ArrayList<>();
		for (final Task t : taskList) {
			stimuliList.add(CommonUtils.getStimInTime(t));
		}
		/* Sorting (Shortest Period(Time) first) */
		Collections.sort(stimuliList, new TimeComp());
		/* Sort tasks to the newTaskList in order of Period length (shortest first
		 * longest last)-(according to the stimuliList) */
		final List<Task> newTaskList = new ArrayList<>();
		for (int i = 0; i < stimuliList.size(); i++) {
			for (final Task t : taskList) {
				if ((!newTaskList.contains(t)) && (stimuliList.get(i).compareTo(CommonUtils.getStimInTime(t)) == 0)) {
					newTaskList.add(t);
				}
			}
		}
		return newTaskList;
	}
	
	/**
	 * To check whether or not the observed task is mapped to CPU (according to the integer array)
	 * @param task				the observed task
	 * @param cpurta			the instance of CPURta class that contains model & mapping IA info
	 * @return
	 * 				boolean value that says whether or not it is mapped to CPU
	 */
	private static boolean isMappedToCPU (final Task task, final CPURta cpurta) {
		/* The observed task is a GPU task */
		if (cpurta.getGpuTaskList().contains(task)) {
			final int index = cpurta.getModel().getSwModel().getTasks().indexOf(task);
			final int cpuThreshold = CommonUtils.getNumberofCPUs(cpurta.getModel()) - 1;
			final int[] ia = cpurta.getIA();
			/* when the observed GPU task is mapped to GPU */
			if (ia[index] > cpuThreshold) {
				return false;
			}
		}
		/* when the observed task(CPU or GPU) is mapped to CPU */
		return true;
	}
}

/**
 * @Date: August 21-2019
 * @version 1.0
 *			This inner class is used for sorting a Time type list.
 *			If the Time of a is smaller than that of b, it returns -1.
 *			If the Time of a is bigger than that of b, it returns 1.
 */
class TimeComp implements Comparator<Time> {
	@Override
	public int compare(final Time a, final Time b) {
		if (a.compareTo(b) < 0) {
			return -1;
		}
		return 1;
	}
}

/**
 * @Date: August 21-2019
 * @version 1.0
 *			This inner class is used for the method "letCom" to help compare between different values of propagation, age, reaction
 *			in basicPaths (which is bigger)
 *			If the BigDecimal of a is smaller than that of b, it returns -1.
 *			If the BigDecimal of a is bigger than that of b, it returns 1.
 */
class BigDecimalComp implements Comparator<BigDecimal> {
	@Override
	public int compare(final BigDecimal a, final BigDecimal b) {
		if (a.compareTo(b) < 0) {
			return -1;
		}
		return 1;
	}
}