package cz.muni.fi.lasaris.sbms.api;

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import cz.muni.fi.lasaris.sbms.api.entities.DataPoint;
import cz.muni.fi.lasaris.sbms.api.entities.Influence;
import cz.muni.fi.lasaris.sbms.api.entities.ObservedProperty;
import cz.muni.fi.lasaris.sbms.api.entities.Scope;
import cz.muni.fi.lasaris.sbms.api.entities.Sensing;
import cz.muni.fi.lasaris.sbms.api.entities.Source;
import cz.muni.fi.lasaris.sbms.api.request.DataPointsRequest;
import cz.muni.fi.lasaris.sbms.api.response.DataPointsResponse;
import cz.muni.fi.lasaris.sbms.model.QueryParser;

@Path("trends")
@PermitAll
public class TrendsEndpoint {
final static Logger logger = Logger.getLogger(DataPointsEndpoint.class);
	
	@Context
	private UriInfo uriInfo;
	
	@RolesAllowed({"user","admin"})
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public DataPointsResponse getTrends(
			@QueryParam("bmsId") String dpIdP,
			@QueryParam("type") String dptP,
			@QueryParam("source.bimId") String sourceIdP,
			@QueryParam("source.type") String sourceTypeP,
			@QueryParam("source.location") String sourceLocP,
			@QueryParam("scope.bimId") String scopeIdP,
			@QueryParam("scope.type") String scopeTypeP,
			@QueryParam("scope.location") String scopeLocP,
			@QueryParam("sensing.type") String sensingTypeP,
			@QueryParam("sensing.window") String sensingWindowP,
			@QueryParam("property.domain") String propDomP,
			@QueryParam("property.quality") String propQualityP,
			@QueryParam("influenced.scope.bimId") String inflScopeIdP,
			@QueryParam("influenced.property.quality") String inflQualityP,
			@QueryParam("influenced.property.domain") String inflDomainP,
			@QueryParam("fields") String fieldsP,
			@QueryParam("grouping") String groupingP
			) {
		DataPointsRequest dpr = new DataPointsRequest();
		DataPoint dp = new DataPoint();
		dpr.setDataPoint(dp);
		
		if(dpIdP != null) {
			dp.setBmsId(dpIdP);
		}
		
		if(dptP != null) {
			dp.setType(dptP);
		}
		
		if(sourceIdP != null || sourceTypeP != null || sourceLocP != null) {
			Source s = new Source(sourceIdP, sourceTypeP, sourceLocP);
			dp.setSource(s);
		}
		
		if(scopeIdP != null || scopeTypeP != null  || scopeLocP != null) {
			Scope s = new Scope(scopeIdP, scopeTypeP, scopeLocP);
			dp.setScope(s);
		}
		
		if(sensingTypeP != null || sensingWindowP != null) {
			Sensing s = new Sensing(sensingTypeP, sensingWindowP);
			dp.setSensing(s);
		}
		
		if(propDomP != null || propQualityP != null) {
			ObservedProperty p = new ObservedProperty(propQualityP, propDomP);
			dp.setProperty(p);
		}
		
		ObservedProperty ip = null;
		Scope is = null;
		if(inflScopeIdP != null) {
			is = new Scope(inflScopeIdP, null, null);
		}
		if(inflQualityP != null || inflDomainP != null) {
			ip = new ObservedProperty(inflQualityP, inflDomainP);
		}
		
		if(ip != null || is != null) {
			Influence i = new Influence(ip, is);
			dp.setInfluence(i);
		}
		
		dpr.setGrouping(groupingP);
		
		setResponseFields(fieldsP, dpr);
		try {
			return QueryParser.getDataPoints(dpr);
		} catch (Exception e){
			logger.info(e.toString());
			e.printStackTrace();
			DataPointsResponse r = new DataPointsResponse();
			r.setError(e.toString());
			return r;
		}
	}
	
	private void setResponseFields(String fields, DataPointsRequest dpr) {
		if(fields != null) {
			for(String f : fields.split(",")) {
				if(StringUtils.isNotEmpty(f)) {
					dpr.getResponseFields().add(f);
				}
				dpr.getResponseFields().add("trendId");
			}
		}
	}
}
