/*
 * ARISTOTLE UNIVERSITY OF THESSALONIKI
 * Copyright (C) 2015
 * Aristotle University of Thessaloniki
 * Department of Electrical & Computer Engineering
 * Division of Electronics & Computer Engineering
 * Intelligent Systems & Software Engineering Lab
 *
 * Project             : eticsbte
 * WorkFile            : 
 * Compiler            : 
 * File Description    : 
 * Document Description: 
* Related Documents	   : 
* Note				   : 
* Programmer		   : RESTful MDE Engine created by Christoforos Zolotas
* Contact			   : christopherzolotas@issel.ee.auth.gr
*/

package eu.fp7.scase.eticsbte.optimize;

import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

import javax.ws.rs.core.UriInfo;
import javax.ws.rs.WebApplicationException;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;

import eu.fp7.scase.eticsbte.utilities.HypermediaLink;
import eu.fp7.scase.eticsbte.utilities.HibernateController;



/* 
 *This class processes client requests for optimize resource that are to be delegated to an existing 3rd party service. 
 *Uppon its output receival, this class repackages the output and creates the hypermedia links with the search results to be returned to the client
*/
public class PostoptimizeHandler{

    private HibernateController oHibernateController;
    private UriInfo oApplicationUri; //Standard datatype that holds information on the URI info of this request
    private JavaAlgooptimizeModel oJavaAlgooptimizeModel;
	private JavaOptimizeOutputModel oOutputDataModel;
	private String searchVirtualMachineCpuPower;
	private String searchVirtualMachineHdDimension;
	private String searchKeyword;
	private String searchVirtualEnvironmentType;
	private ClientConfig oClientConfiguration;

    public PostoptimizeHandler(String searchVirtualMachineCpuPower, String searchVirtualMachineHdDimension, String searchKeyword, String searchVirtualEnvironmentType, JavaAlgooptimizeModel oTempJavaAlgooptimizeModel, UriInfo oApplicationUri){
        oJavaAlgooptimizeModel = new JavaAlgooptimizeModel();
        this.oHibernateController = HibernateController.getHibernateControllerHandle();
        this.oApplicationUri = oApplicationUri;
    	this.oJavaAlgooptimizeModel = oTempJavaAlgooptimizeModel;
		this.searchVirtualMachineCpuPower = searchVirtualMachineCpuPower;
		this.searchVirtualMachineHdDimension = searchVirtualMachineHdDimension;
		this.searchKeyword = searchKeyword;
		this.searchVirtualEnvironmentType = searchVirtualEnvironmentType;

		//initialize JAX-RS Client configuration 
		this.oClientConfiguration = new DefaultClientConfig();
		this.oClientConfiguration.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
    }

    public JavaOptimizeOutputModel postoptimize(){


		//Return any results in the hypermedia links form.
        return interoperateWithExternalService();
    }


    /* 
	 * This function handles the interoperation with the existing 3rd party service. It calls the according functions to create the input 
	 * to be sent to it, to receive its output and if necessary to persist the outcome in the database. 
	 * Finally, the result is returned to the client.
    */
    public JavaOptimizeOutputModel interoperateWithExternalService(){
		
		//create a new JAX-RS client
        Client oJAXRSRESTClient = Client.create(this.oClientConfiguration);

		//construct the POST query
		WebResource oTargetResource = oJAXRSRESTClient.resource("http://localhost:8080/eticsbte/api/AlgosearchVirtualMachine").queryParam("searchVirtualMachineCpuPower", this.searchVirtualMachineCpuPower).queryParam("searchVirtualMachineHdDimension", this.searchVirtualMachineHdDimension).queryParam("searchKeyword", this.searchKeyword).queryParam("searchVirtualEnvironmentType", this.searchVirtualEnvironmentType);
        ClientResponse oResponse = oTargetResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).accept(javax.ws.rs.core.MediaType.APPLICATION_JSON).post(ClientResponse.class, this.oJavaAlgooptimizeModel);
        this.oOutputDataModel = oResponse.getEntity(JavaOptimizeOutputModel.class);

        if (isSuccessfullResponseCode(oResponse) == false) {
            throw new WebApplicationException();
        }	

		return this.oOutputDataModel;
	}

	/*
	 * This function checks the response code of the server reply against the known success codes. If the server response HTTP
     * code is within the success code range, this functions returns true. Otherwise it returns false
	*/
	private boolean isSuccessfullResponseCode(ClientResponse oResponse){
		if(oResponse.getStatus() == 200){ // Status OK
			return true;
		}
		else if(oResponse.getStatus() == 201){ // Status CREATED
			return true;
		}
		else if(oResponse.getStatus() == 202){ // Status Accepted
			return true;
		}
		else if(oResponse.getStatus() == 203){ // Status NON-AUTHORITATIVE INFORMATION
			return true;
		}
		else if(oResponse.getStatus() == 204){ // Status NO CONTENT
			return true;
		}
		else if(oResponse.getStatus() == 205){ // Status RESET CONTENT
			return true;
		}
		else if(oResponse.getStatus() == 206){ // Status PARTIAL CONTENT
			return true;
		}

		return false;
	}
	
}
