package pulling.availability_imposer;

import java.io.Serializable;

/**
 * This class represents a Node in the Availability node.
 * Every node represents a state of availability for the server.
 * 
 * @author Majd Kokaly
 *
 */
public class Node implements Serializable {
	
	/**
	 * The serialVersionUID is used to universally identify this version of this
	 * class.
	 */
	private static final long serialVersionUID = 3829862197493899372L;
	/**
	
	 * The specific amount of availability for this Node
	 */
	private double aj;
	
	/**
	 * An optional textual description
	 */
	private String description;
	
	/**
	 * The time to stay in that node.
	 */
	private long periodToStay;
	
	/**
	 * An array of arches connecting this Node to other nodes
	 */
	private java.util.LinkedList<Arch> archs;
	
	/**
	 * A flag used in traversing
	 */
	protected boolean visited = false;
	
	/**
	 * The default constructor
	 * @param aj
	 * @param description
	 * @param periodToStay
	 */
	public Node(double aj, String description, long periodToStay) {
		this.setAj(aj);
		this.setDescription(description);
		this.setPeriodToStay(periodToStay);
		archs = new java.util.LinkedList<Arch>();
	}
	
	
	protected double getAj() {
		return aj;
	}
	protected void setAj(double aj) {
		this.aj = aj;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public long getPeriodToStay() {
		return periodToStay;
	}
	public void setPeriodToStay(long periodToStay) {
		this.periodToStay = periodToStay;
	}
	public java.util.LinkedList<Arch> getArchs() {
		return archs;
	}
	public void setArchs(java.util.LinkedList<Arch> archs) {
		this.archs = archs;
	}
	/**
	 * This method is used to add an Arch.
	 * @param probability is the probability of the added node.
	 * @param distinatioNode is the destination node.
	 */
	public void addArch( double probability, Node distinatioNode ){
		Arch arch = new Arch(probability, distinatioNode);
		this.archs.add(arch);
	}
	
	/**
	 * This method checks if the sum of the probabilities of Arches are valid
	 * @return true if sum equals one
	 */
	public boolean isSumValid() {
		double sum = 0;
		for (int i = 0; i < archs.size(); i++) {
			sum+= archs.get(i).getProbability();
		}
		if (sum > 0.999 && sum < 1.001)
			return true;
		else return false;
	}
	
	/**
	 * 
	 * @return the number of Nodes connected to this Node
	 */
	public int getNeighboursNumber() {
		return this.getArchs().size();
	}
	
	/**
	 * @param i a number
	 * @return returns the ith neighbouring node
	 */
	public Node getNeighbour(int i) {
		return this.getArchs().get(i).getDestinationNode();
	}
	
	/**
	 * @param i a number
	 * @return returns the probability of the arch connecting to the ith neighbouring node
	 */
	public double getPropability(int i) {
		return this.getArchs().get(i).getProbability();
	}
	public String toString() {
		return this.getDescription() + ",\nTime to stay: " +  this.getPeriodToStay() + "\nAvailability: " + this.getAj() + "\nArchs: " + archs.toString() +"\n";
	}
	public void  visit() {
		this.print();
		this.visited = true;
	}
	public void print() {
		System.out.print(this.toString());
	}
	
	
	
}
