/**
 * 2007(C) jarwyp@icm.edu.pl
 *
 * project: DRIVER
 * module : AAS
 * package:	eu.dnetlib.enabling.aas
 * file:	DriverPDP.java
 * date:    2007-02-19
 *
 */
package eu.dnetlib.enabling.aas;

import java.util.ArrayList;

import org.apache.log4j.Logger;


import com.sun.xacml.PDP;
import com.sun.xacml.PDPConfig;
import com.sun.xacml.ParsingException;
import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.ctx.Result;
import com.sun.xacml.ctx.Status;
import com.sun.xacml.finder.AttributeFinder;

import eu.dnetlib.enabling.aas.finder.ctx.DriverEvaluationCtx;
import eu.dnetlib.enabling.aas.rmi.A2Request;
import eu.dnetlib.enabling.aas.rmi.AuthenticateRequest;
import eu.dnetlib.enabling.aas.rmi.AuthorizeRequest;
import eu.dnetlib.enabling.aas.service.A2Exception;
import eu.dnetlib.enabling.aas.utils.DriverConverter;

/**
 * Driver PDP module.
 * 
 * @author talen
 * @author mhorst
 *
 */
public class DriverPDP extends PDP {

	protected static final Logger log = Logger.getLogger(DriverPDP.class);
	
	private AttributeFinder attributeFinder;
	
	public static final String RESOLVABLE_OBLIGATION_PREFIX = "designate:";
	
	/**
	 * @param config
	 */
	public DriverPDP(PDPConfig config) {
		super(config);
		attributeFinder = (AttributeFinder) config.getAttributeFinder();
	}

	/**
	 * Evaluates CtxResponse for given A2Request as parameter.
	 * @param authReq
	 * @return
	 */
	public ResponseCtx evaluate(A2Request authReq) throws A2Exception{
		if (authReq instanceof AuthenticateRequest) {
			RequestCtx reqCtx = DriverConverter.convertRequest((AuthenticateRequest)authReq);
			if (reqCtx!=null)
				return evaluate(reqCtx, authReq);
			else
				throw new A2Exception("Couldn't convert authenticateRequest!");
		} else if (authReq instanceof AuthorizeRequest) {
			RequestCtx reqCtx = DriverConverter.convertRequest((AuthorizeRequest)authReq);
			if (reqCtx!=null)
				return evaluate(reqCtx, authReq);
			else
				throw new A2Exception("Couldn't convert authorizeRequest!");
		} else
			throw new A2Exception("Unsupported A2Request impl class!"); 
	}
	
	
	/**
	 * Evaluates CtxResponse for given RequestCtx and A2Request parameters.
	 * A2Request is used as a source of attributes for A2RequestFinderModules.
	 * @param reqCtx
	 * @param authReq
	 * @return ResponseCtx
	 */
	@SuppressWarnings("unchecked")
	ResponseCtx evaluate(RequestCtx reqCtx, A2Request authReq) {
        try {
        	DriverEvaluationCtx driverEvalCtx = new DriverEvaluationCtx(reqCtx, attributeFinder, authReq); 
            ResponseCtx responseCtx = evaluate(driverEvalCtx);
//          resolveing obligations (if we have defined some designators)
            responseCtx = ObligationsResolver.resolveObligations(responseCtx, driverEvalCtx);
            return responseCtx;
        } catch (ParsingException pe) {
        	log.error("the PDP receieved an invalid request", pe);
            // there was something wrong with the request, so we return
            // Indeterminate with a status of syntax error...though this
            // may change if a more appropriate status type exists
            ArrayList code = new ArrayList();
            code.add(Status.STATUS_SYNTAX_ERROR);
            Status status = new Status(code, pe.getMessage());
            return new ResponseCtx(new Result(Result.DECISION_INDETERMINATE,
                                              status));
        }
	}
	
}
