/**
 * 
 */
package com.fp.alfresco.util;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import com.fp.alfresco.auth.AlfrescoFileAuth;
import com.fp.alfresco.auth.Authentication;
import com.fp.alfresco.enums.EnumRequestType;
import com.fp.alfresco.exception.ExceptionWebscript;


/**
 * 
 * Clase que gestiona las peticiones realizadas en el API de Alfresco
 * @author bpt
 *
 */
public class ApiRequest {
    private String uriBase = ApiProperties.getProperty("api.uri.base");

    private CloseableHttpClient  client = HttpClients.createDefault();

    private Authentication auth = new AlfrescoFileAuth();

    /**
     * Retorna una respuesta a una petici&oacute;n REST simple
     * @param requestType tipo de petici&oacute;n
     * @param uri URI 
     * @return respuesta a la petici&oacute;n REST
     * @throws Exception
     */
    public String simpleRequest(EnumRequestType requestType, String uri) throws Exception{
	HttpRequestBase httpRequest;
	uri = this.uriBase+uri;

	if(requestType==EnumRequestType.GET){
	    httpRequest = new HttpGet(uri);
	}else{
	    httpRequest = new HttpPost(uri);
	}
	ApiResponseHandler handler = new ApiResponseHandler();
	CloseableHttpResponse response = this.client.execute(httpRequest);
	return handler.handleResponse(response);
    }

    /**
     * M&eacute;todo de autenticaci&oacute;n de acceso al repositorio de Alfresco
     * @param requestType tipo de petici&oacute;n
     * @param uri URI  de la petici&oacute;n
     * @param isOnlyTicket si es solo ticket
     * @param entity objeto en la request
     * @param isGetEntityContent retorna contenido en la petici&oacute;n REST
     * @return un objeto con la respuesta a la autenticaci&oacute;
     * @throws Exception
     */
    private Object authRequest(EnumRequestType requestType, String uri, boolean isOnlyTicket, HttpEntity entity, boolean isGetEntityContent) throws Exception{
	uri = this.uriBase+uri;
	if(this.auth.authenticate()){
	    if(isOnlyTicket) {
		uri+= "?alf_ticket=" + this.auth.getTicket();
	    }else{
		uri+= "&alf_ticket=" + this.auth.getTicket();
	    }
	    HttpRequestBase httpRequest;
	    if(requestType==EnumRequestType.GET){
		httpRequest = new HttpGet(uri);
	    }else if(requestType==EnumRequestType.POST){
			httpRequest = new HttpPost(uri);
			if(entity!=null){
			    ((HttpPost)httpRequest).setEntity(entity);
			}
	    }else {
	    	httpRequest = new HttpDelete(uri);
	    }
	    ApiResponseHandler handler = new ApiResponseHandler();
	    CloseableHttpResponse  response = this.client.execute(httpRequest);
//	    try {
	    return handler.handleResponse(response, isGetEntityContent);
//	    }finally {
		//response.close();
//	    }
	}else{
	    throw new ExceptionWebscript("Error al autenticar con alfresco");
	}
    }

    /**
     * M&eacute;todo de autenticaci&oacute;n de acceso al repositorio de Alfresco
     * @param requestType tipo de petici&oacute;n
     * @param uri URI  de la petici&oacute;n
     * @return un objeto con la respuesta a la autenticaci&oacute;
     * @throws Exception
     */
    public Object authRequest(EnumRequestType requestType, String uri) throws Exception{
	return this.authRequest(requestType, uri, false, null, false);
    }

    /**
     * M&eacute;todo de autenticaci&oacute;n de acceso al repositorio de Alfresco
     * @param requestType tipo de petici&oacute;n
     * @param uri URI  de la petici&oacute;n
     * @param entity objeto en la request
     * @return un objeto con la respuesta a la autenticaci&oacute;
     * @throws Exception
     */
    public Object authRequest(EnumRequestType requestType, String uri, HttpEntity entity) throws Exception{
	return this.authRequest(requestType, uri, false, entity, false);
    }

    /**
     * M&eacute;todo de autenticaci&oacute;n de acceso al repositorio de Alfresco
     * @param requestType tipo de petici&oacute;n
     * @param uri URI  de la petici&oacute;n
     * @param isGetEntityContent retorna contenido en la petici&oacute;n REST
     * @return un objeto con la respuesta a la autenticaci&oacute;
     * @throws Exception
     */
    public Object authRequest(EnumRequestType requestType, String uri, boolean isGetEntityContent) throws Exception{
	return this.authRequest(requestType, uri, false, null, isGetEntityContent);
    }

    /**
     * M&eacute;todo de autenticaci&oacute;n de acceso al repositorio de Alfresco
     * @param requestType tipo de petici&oacute;n
     * @param uri URI  de la petici&oacute;n
     * @param isGetEntityContent retorna contenido en la petici&oacute;n REST
     * @param isOnlyTicket si es solo ticket
     * @return un objeto con la respuesta a la autenticaci&oacute;
     * @throws Exception
     */
    public Object authRequest(EnumRequestType requestType, String uri, boolean isGetEntityContent, boolean includeTicket) throws Exception{
	return this.authRequest(requestType, uri, includeTicket, null, isGetEntityContent);
    }

    /**
     * @return Retorna el atributo auth
     */
    public Authentication getAuth() {
	return this.auth;
    }

    /**
     * @param auth Par&aacute;metro a fijar en el atributo auth
     */
    public void setAuth(Authentication auth) {
	this.auth = auth;
    }

}
