package com.libreecm.consumers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.libreecm.commonAPI.auxiliars.exceptions.ErrorConsumingRESTException;
import com.libreecm.commonAPI.model.AclCapabilities;
import com.libreecm.commonAPI.model.CmisExtensionElement;
import com.libreecm.commonAPI.model.CreatablePropertyTypes;
import com.libreecm.commonAPI.model.NewTypeSettableAttributes;
import com.libreecm.commonAPI.model.Repository;
import com.libreecm.commonAPI.model.RepositoryCapabilities;
import com.libreecm.commonAPI.model.objects.ObjectType;
import com.libreecm.commonAPI.model.objects.properties.PropertyDefinition;

public class RepositoryConsumer {
	
	RestTemplate restTemplate = new RestTemplate();
	ObjectMapper mapper = new ObjectMapper();
	
	public RepositoryConsumer(){		 
	}
	
	
	public Repository getRepository(String name, String url){
		Repository repository = null;
		try {
			repository = restTemplate.getForObject(url+"?name="+name, Repository.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url+"?name="+name);
		}
		return repository;
	}
	
	public List<Repository> getRepositories(String url){
		ObjectMapper mapper = new ObjectMapper();
		List<Repository> repositories =null;
		try {
			repositories =  restTemplate.getForObject(url, List.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		
		List<Repository> pojos = mapper.convertValue(repositories, new TypeReference<ArrayList<Repository>>() { });
		return pojos;
	}
	
	public CmisExtensionElement getCmisExtensionElement(String id, String url){
		try {
			return restTemplate.getForObject(url+"?id="+id, CmisExtensionElement.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url+"?id="+id);
		}
		
	}
	

	public List<ObjectType> getTypeChildren(String repositoryId, String typeId,
			String url) {
		List<ObjectType> result=null;
		try {
			result =  restTemplate.getForObject(url+"?repositoryid="+repositoryId+"&typeid"+typeId, List.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		List<ObjectType> pojos = mapper.convertValue(result, new TypeReference<ArrayList<ObjectType>>() { });
				
		return pojos;
	}

	
	public CmisExtensionElement setExtension(CmisExtensionElement el, String url){
		try {
			return  restTemplate.postForObject(url, el, CmisExtensionElement.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		
	}
	
	public RepositoryCapabilities setRepositoryCapabilities(RepositoryCapabilities rep, String url){
		try {
			return restTemplate.postForObject(url, rep, RepositoryCapabilities.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		
	}

	public AclCapabilities setAclCapabilitities(AclCapabilities aclCapabilities, String url){
		try {
			return (restTemplate.postForObject(url, aclCapabilities, AclCapabilities.class));
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		
	}
	
	public CreatablePropertyTypes setCreatablePropertyTypes(CreatablePropertyTypes creat, String url){
		try {
					return restTemplate.postForObject(url, creat, CreatablePropertyTypes.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		
	}
	
	public Repository setRepository(Repository repository, String url){
	try {	
		repository= restTemplate.postForObject(url, repository, Repository.class);
		return repository;
	} catch (HttpClientErrorException e){
		throw new ErrorConsumingRESTException(url);
	}
	}

	public NewTypeSettableAttributes setNewTypeSettableAttributes(NewTypeSettableAttributes newTypeSettableAttributes,
			String url) {
	try{
		return restTemplate.postForObject(url, newTypeSettableAttributes, NewTypeSettableAttributes.class);
	} catch (HttpClientErrorException e){
		throw new ErrorConsumingRESTException(url);
	}
	
	}

	public NewTypeSettableAttributes getNewTypeSettableAttributes(String id, String url) {
		try {
			return restTemplate.getForObject(url+"?id="+id, NewTypeSettableAttributes.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
	}

	
	public <T> PropertyDefinition<T> getPropertyDefinition(String id, String url){
		try{
			return restTemplate.getForObject(url+"?id="+id, PropertyDefinition.class);
		}catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
	}

/**
 * This checks if a repository exists and it's readable
 * and updates some information about it
 * Doesn't read cache, but updates it
 * @param repository
 * @param inputRepositoryUrl
 * @return
 */
	public Repository getRepository(Repository repository, String url) {
		try {
			repository = restTemplate.postForObject(url, repository, Repository.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		return repository;
	}


public Repository getRepositoryById(String id, String url) {
	Repository repository = null;
	try {
		repository = restTemplate.getForObject(url+"?id="+id, Repository.class);
	} catch (HttpClientErrorException e){
		throw new ErrorConsumingRESTException(url+"?id="+id);
	}
	return repository;
}
	
}
