package eu.dnetlib.contract.node;

import org.contract4j5.contract.Contract;
import org.contract4j5.contract.Post;
import org.contract4j5.contract.Pre;

import eu.dnetlib.contract.cp.ICheckPoint;
import eu.dnetlib.contract.event.IContractEvent;


/**
 * Check point result object.
 * @author mhorst
 *
 */
@Contract
public class EvaluationResult {
	
	public enum Status {
		OK,
		WARN,
		FAIL,
		FATAL
	}
	
	/**
	 * Result check point status.
	 */
	private Status status;
	
	/**
	 * Related {@link IContractDefinitionNode} for which the result was created.
	 */
	private IContractDefinitionNode relatedNode;
	
	/**
	 * Related {@link IContractEvent} which triggered evaluation.
	 */
	private IContractEvent relatedEvent;
	
	/**
	 * Detailed message for the result.
	 */
	private String message;
	
	/**
	 *Throwable object e.g. when exception occured. 
	 */
	private Throwable throwable;

	/**
	 * 
	 * @param status result status
	 * @param node
	 * @param event
	 */
	@Pre("status != null && relatedCheckPoint != null")
	public EvaluationResult(Status status, IContractDefinitionNode node, IContractEvent event) {
		this.status = status;
		this.relatedNode = node;
		this.relatedEvent = event;
	}
	
	@Pre("status != null && relatedCheckPoint != null")
	public EvaluationResult(Status status, IContractDefinitionNode node, IContractEvent event,
			String message) {
		this(status, node, event);
		this.message = message;
	}
	
	@Pre("status != null && relatedCheckPoint != null")
	public EvaluationResult(Status status, IContractDefinitionNode node, IContractEvent event,
			String message, Throwable throwable) {
		this(status, node, event);
		this.message = message;
		this.throwable = throwable;
	}
	
	/**
	 * 
	 * @param status result status
	 * @param relatedCheckPoint
	 * @param event
	 * @param message detailed message
	 */
	@Pre("status != null && relatedCheckPoint != null")
	public EvaluationResult(Status status, ICheckPoint<IContractEvent> relatedCheckPoint, 
			IContractEvent event, String message) {
		this(status,relatedCheckPoint, event);
		this.message = message;
	}
	
	/**
	 * @param status result status
	 * @param relatedCheckPoint
	 * @param event
	 * @param message detailed message
	 * @param throwable itercepted exception
	 */
	@Pre("status != null && relatedCheckPoint != null")
	public EvaluationResult(Status status, ICheckPoint<IContractEvent> relatedCheckPoint, 
			IContractEvent event, String message, Throwable throwable) {
		this(status, relatedCheckPoint, event, message);
		this.throwable = throwable;
	}
	
	/**
	 * 
	 * @param status result status
	 * @param relatedCheckPoint
	 * @param event
	 * @param throwable itercepted exception
	 */
	@Pre("status != null && relatedCheckPoint != null")
	public EvaluationResult(Status status, ICheckPoint<IContractEvent> relatedCheckPoint, 
			IContractEvent event, Throwable throwable) {
		this(status, relatedCheckPoint, event);
		this.throwable = throwable;
	}
	
	/**
	 * Returns result check point status.
	 * @return result check point status
	 */
	@Post("$return != null")
	public Status getStatus() {
		return status;
	}

	/**
	 * Sets result check point status.
	 * @param status
	 */
	@Pre("status != null")
	public void setStatus(Status status) {
		this.status = status;
	}

	/**
	 * Returns detailed message for the result.
	 * @return detailed message for the result
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * Sets detailed message for the result.
	 * @param message
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * Returns Throwable object.
	 * @return Throwable object
	 */
	public Throwable getThrowable() {
		return throwable;
	}

	/**
	 * Sets Throwable object.
	 * @param throwable
	 */
	public void setThrowable(Throwable throwable) {
		this.throwable = throwable;
	}

	/**
	 * Returns related node.
	 * @return related node
	 */
	public IContractDefinitionNode getRelatedNode() {
		return relatedNode;
	}

	/**
	 * Returns related event.
	 * @return related event
	 */
	public IContractEvent getRelatedEvent() {
		return relatedEvent;
	}
}
