package com.libreecm.input.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;

public class RepositoryConsumer {
	
	RestTemplate restTemplate = new RestTemplate();
	ObjectMapper mapper = new ObjectMapper();
	
	HashMap<String,Repository> cache = new HashMap<String,Repository>();
	
	public RepositoryConsumer(){		 
	}
	 
	public Repository getRepository(String name, String url){
		Repository repository = null;
		if (cache.containsKey(name))
			return cache.get(name);
		try {
			repository = restTemplate.getForObject(url+"?name="+name, Repository.class);
			cache.put(name, repository);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		
		return repository;
	}
	
	public List<Repository> getRepositories(String url){
		List<Repository> repositories =  null;
		try {
			repositories= restTemplate.getForObject(url, List.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		
		if (repositories == null || repositories.isEmpty()){
			return null;
		}
		
		List<Repository> pojos = mapper.convertValue(repositories, new TypeReference<ArrayList<Repository>>() { });
		
		for (Repository repo : pojos)
			if (!cache.containsKey(repo.getName())){
				cache.put(repo.getName(), repo);
			}
		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);
		}
		
	}
	
	public CmisExtensionElement setExtension(CmisExtensionElement el, String url){
		//CmisExtensionElement element = el;
		/*
			for (CmisExtensionElement el1: element.getChildren()){
				try {	
					element.getChildren().remove(el1);
					element.getChildren().add(setExtension(el1, url));
				} catch (Exception e){		
				}
			}*/
		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);
			this.cache.put(repository.getName(), repository);
			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 ObjectType getObjectType(String id, String url) {
		ObjectType result=null;
		try {
			result = restTemplate.getForObject(url+"?id="+id, ObjectType.class);
		}	catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		return result;
		
	}
	public List<ObjectType> getTypeChildren(String repositoryName, String typeId,
			String url) {
		List<ObjectType> result=null;
		try {
			result =  restTemplate.getForObject(url+"?repositoryName="+repositoryName+"&typeid"+typeId, List.class);
		} catch (HttpClientErrorException e){
			throw new ErrorConsumingRESTException(url);
		}
		List<ObjectType> pojos = mapper.convertValue(result, new TypeReference<ArrayList<ObjectType>>() { });
			
		return pojos;
	}
}
