package dfatool.strategy.elements.patterns;

import java.util.List;
import java.util.Map;
import java.util.Set;

import dfatool.expressions.Expression;
import dfatool.expressions.ListExpression;
import dfatool.expressions.SetExpression;
import dfatool.expressions.TupleExpression;
import dfatool.parser.LanguageUtil;
import dfatool.strategy.elements.Configuration;
import dfatool.strategy.elements.Context;
import dfatool.strategy.graph.NodeIdentifier;
import dfatool.values.IntValue;
import dfatool.values.SetValue;
import dfatool.values.ListValue;
import dfatool.values.Value;

public class ResourceAllocationDescription {
	
	private Expression users;
	private Expression resources;
	private Map<String,Expression> funUser;
	private Map<String,Expression> funResources;
	private Map<String,Map<String,Expression>> acquireFunc; 
	private Map<String,Map<String,Expression>> releaseFunc; 
	
	
		
	public ResourceAllocationDescription(Expression users,
			Expression resources, Map<String, Expression> funUser,
			Map<String, Expression> resourceFunc,
			Map<String, Map<String, Expression>> acquireFunc,
			Map<String, Map<String, Expression>> releaseFunc) {
		this.users = users;
		this.resources = resources;
		this.funUser = funUser;
		this.funResources = resourceFunc;
		this.acquireFunc = acquireFunc;
		this.releaseFunc = releaseFunc;
	}

	public Set<Value> getUsers(NodeIdentifier id) {
		Expression funUsersId = funUser.get(id.getFst());
		Set<Value> usersId = (SetValue) LanguageUtil.evalWithId(funUsersId, id.getSnd());
		return usersId;
	}

	public List<Value> getResources(NodeIdentifier id) {
		Expression funResourcesId = funResources.get(id.getFst());
		ListValue resourcesId = (ListValue) LanguageUtil.evalWithId(funResourcesId, id.getSnd());
		return resourcesId;
	}
	
	public ListValue getAcquireEvent(NodeIdentifier idUser, NodeIdentifier idResource){
		Expression funAcq = acquireFunc.get(idUser.getFst()).get(idResource.getFst());
		Context c = Configuration.getInstance().getContext();
		c.getVarMap().put("idU", new IntValue(idUser.getSnd()));
		c.getVarMap().put("idR", new IntValue(idResource.getSnd()));
		ListValue acqEvent = (ListValue) funAcq.evaluate(c);
		return acqEvent;
	}
	
	public ListValue getReleaseEvent(NodeIdentifier idUser, NodeIdentifier idResource){
		Expression funRel = releaseFunc.get(idUser.getFst()).get(idResource.getFst());
		Context c = Configuration.getInstance().getContext();
		c.getVarMap().put("idU", new IntValue(idUser.getSnd()));
		c.getVarMap().put("idR", new IntValue(idResource.getSnd()));
		ListValue relEvent = (ListValue) funRel.evaluate(c);
		return relEvent;
	}


	public Set<Value> getUsers() {
		return (SetValue) users.evaluate(Configuration.getInstance().getContext());
	}

	public Set<Value> getResources() {
		return (SetValue) resources.evaluate(Configuration.getInstance().getContext());
	}

	public Map<String, Expression> getFunUser() {
		return funUser;
	}

	public Map<String, Expression> getFunResources() {
		return funResources;
	}

	public Map<String, Map<String, Expression>> getAcquireFunc() {
		return acquireFunc;
	}

	public Map<String, Map<String, Expression>> getReleaseFunc() {
		return releaseFunc;
	}
	
	
	
	

}
