package com.libreecm.controllers;


import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.libreecm.commonAPI.auxiliars.exceptions.AddObjectOkException;
import com.libreecm.commonAPI.auxiliars.exceptions.AlreadyExistingObjectException;
import com.libreecm.commonAPI.configuration.ComponentConfig;
import com.libreecm.commonAPI.model.objects.ExtensionDataImpl;
import com.libreecm.commonAPI.model.enums.IncludeRelationships;
import com.libreecm.commonAPI.model.objects.LibreECMDataObject;
import com.libreecm.commonAPI.model.objects.ObjectType;
import com.libreecm.commonAPI.model.objects.Uri;
import com.libreecm.consumers.ObjectConsumer;

@RestController
public class ObjectController extends BaseController{

    private ObjectConsumer consumer= new ObjectConsumer();

    @Autowired
	RepositoryController repoController;

    
    @RequestMapping(value="/object", method = RequestMethod.POST)
    /**
     * A class that saves an Object to the DDBB
     * @param object
     * @return
     */
    public void saveObject(@RequestParam(value="object", required=true) LibreECMDataObject object,
    		@RequestParam(value="filter", required=false) String filter,
    		@RequestParam(value="includeAllowableActions", required=false) boolean includeAllowableActions,
    		@RequestParam(value="includeRelationships", required=false) IncludeRelationships includeRelationships,
    		@RequestParam(value="renditionFilter", required=false) String renditionFilter,
    		@RequestParam(value="includePolicyIds", required=false) boolean includePolicyIds,
    		@RequestParam(value="includeAcl", required=false) boolean includeAcl
    		//Passes as @RequestBody for complexity param
			//@RequestParam(value="includeAcl", required=false) ExtensionDataImpl extension
    		) {
    	//validateUser();
    	
		LibreECMDataObject obj = consumer.getObject(
	    		 object.getId().toString(),
	    		 filter,
	    		 includeAllowableActions,
	    		 includeRelationships,
	    		 renditionFilter,
	    		 includePolicyIds,
	    		 includeAcl,
	    		 //extension, 
	    		 ComponentConfig.getConfig().getInputObjectUrl());
 	   
    	if (obj!=null){
			throw new AlreadyExistingObjectException(object.getId());
    	}
    	//EventHandler.getHandler().preEvent(object);
    	obj = consumer.setObject(object,
	    		 filter,
	    		 includeAllowableActions,
	    		 includeRelationships,
	    		 renditionFilter,
	    		 includePolicyIds,
	    		 includeAcl,
	    		 //extension, 
	    		 ComponentConfig.getConfig().getInputObjectUrl());

    	//EventHandler.getHandler().postEvent(obj);
		throw new AddObjectOkException(obj.getId());
    }

    /**
     * A class that returns a Object from the DDBB
     * @param id
     * @return
     */
	    @RequestMapping(value="/object", method = RequestMethod.GET)
	    public @ResponseBody LibreECMDataObject object(@RequestParam(value="id", required=true) String id,
	    		@RequestParam(value="filter", required=false) String filter,
	    		@RequestParam(value="includeAllowableActions", required=false) boolean includeAllowableActions,
	    		@RequestParam(value="includeRelationships", required=false) IncludeRelationships relationships,
	    		@RequestParam(value="renditionFilter", required=false) String renditionFilter,
	    		@RequestParam(value="includePolicyIds", required=false) boolean includePolicyIds,
	    		@RequestParam(value="includeAcl", required=false) boolean includeAcl
	    		//@RequestParam(value="extension", required=false) ExtensionDataImpl extension
	    		) {
	    	//validateUser();
	    	Uri path = Uri.parse(id);
    		LibreECMDataObject object = consumer.getObject(path.toString(), filter, includeAllowableActions,
	                relationships, renditionFilter, includePolicyIds,
	                includeAcl,// extension,
	                ComponentConfig.getConfig().getInputObjectUrl());
	    	return object;
	    }

		@RequestMapping(value = "/objecttype", method = RequestMethod.GET)
		public @ResponseBody ObjectType getObjectType(@RequestParam(value = "id", required = true) String id,
				@RequestParam(value = "repositoryname", required = true)String repositoryName) {
			ObjectType result=null;
				result = consumer.getObjecType(id, repositoryName, ComponentConfig.getConfig().getInputObjectTypeUrl());
			return result;
		}
		
		@RequestMapping(value = "/objectsinfolder", method = RequestMethod.GET)
		public @ResponseBody Collection<LibreECMDataObject> getObjectsInFolder(@RequestParam(value = "id", required = true)String folderId, 
				@RequestParam(value = "filter", required = false)String filter, 
				@RequestParam(value = "orderby", required = false)String orderBy,
				@RequestParam(value = "includeAllowableActions", required = false)Boolean includeAllowableActions, 
				@RequestParam(value = "includeRelationships", required = false)IncludeRelationships includeRelationships, 
				@RequestParam(value = "renditionFilter", required = false)String renditionFilter,
				@RequestParam(value = "includepathsegment", required = false)Boolean includePathSegment, 
				@RequestParam(value = "maxitems", required = false)BigInteger maxItems, 
				@RequestParam(value = "skipcount", required = false)BigInteger skipCount, 
				@RequestParam(value = "extension", required = false)ExtensionDataImpl extension) {
			// validateUser();
			List<LibreECMDataObject> result = consumer.getChildrenObjects(folderId, filter, orderBy,
					includeAllowableActions, includeRelationships, renditionFilter, includePathSegment,
					maxItems, skipCount, //extension, 
					ComponentConfig.getConfig().getInputObjectsInFolerUrl());
			if (result == null || result.size() == 0) {
				return new ArrayList<LibreECMDataObject>();
			}
			return result;
		}
		

		@RequestMapping(value = "/downloadcontent", method = RequestMethod.GET, produces = MediaType.ALL_VALUE )
		public ByteArrayResource download(@RequestParam("documenturi") String documentUri,
				@RequestParam("offset") Integer offset,
				@RequestParam("length") Integer lenght)
				throws IOException {
		
			return consumer.doDownload(documentUri, offset,
		            lenght,
					ComponentConfig.getConfig().getInputDownloadObjectUrl());
		}

		@RequestMapping(method = RequestMethod.POST, value = "/uploadcontent")
		public String upload(@RequestParam("documenturi") String documentUri,
				@RequestParam("offset") BigInteger offset, @RequestParam("length") BigInteger length,
				@RequestBody ByteArrayResource bytes) {
			
			return consumer.doUpload(documentUri, bytes, offset, length,
					ComponentConfig.getConfig().getInputUploadObjectUrl());
		}
}