package ca.intelliware.ihtsdo.mlds.config;

import java.util.Collection;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

import ca.intelliware.ihtsdo.mlds.domain.Affiliate;
import ca.intelliware.ihtsdo.mlds.domain.json.InternalPrivacyFilter;
import ca.intelliware.ihtsdo.mlds.domain.json.MLDSJacksonModule;
import ca.intelliware.ihtsdo.mlds.repository.MemberRepository;
import ca.intelliware.ihtsdo.mlds.security.ihtsdo.CurrentSecurityContext;
import ca.intelliware.ihtsdo.mlds.web.rest.dto.MemberDTO;

@Configuration
@ConditionalOnClass(ObjectMapper.class)
public class JacksonConfigurer {
	
    private final Logger logger = LoggerFactory.getLogger(JacksonConfigurer.class);

	@Autowired
	private ListableBeanFactory beanFactory;

	@Bean
	public Module mldsModule(final MemberRepository memberRepository, CurrentSecurityContext securityContext) {
		SimpleModule mldsModule = new MLDSJacksonModule(memberRepository, securityContext);
		
		return mldsModule;
	}
	
	@PostConstruct
	public void init() {
		logger.debug("Initialising Jackson Mappers");
		Collection<ObjectMapper> mappers = BeanFactoryUtils
				.beansOfTypeIncludingAncestors(this.beanFactory, ObjectMapper.class)
				.values();
		for (ObjectMapper mapper : mappers) {
			logger.debug("Configuring Jackson mapper: {}", mapper.getTypeFactory().getClass().getName());
			mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
			registerFilters(mapper);
		}
	}

	public void registerFilters(ObjectMapper mapper) {
		logger.debug("Registering jackson privacy filters");
		SimpleFilterProvider filterProvider = new SimpleFilterProvider();
		filterProvider.addFilter("affiliatePrivacyFilter", new InternalPrivacyFilter(Affiliate.PRIVATE_FIELDS) );
		filterProvider.addFilter("memberDtoPrivacyFilter", new InternalPrivacyFilter(MemberDTO.PRIVATE_FIELDS) );
		
		mapper.setFilters(filterProvider);
	}

}

@@ -223,16 +223,82 @@
 yUtils;%0A
+import org.springframework.beans.factory.HierarchicalBeanFactory;%0A
 import o
@@ -414,16 +414,82 @@
 owired;%0A
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;%0A
 import o
@@ -1394,16 +1394,57 @@
 .class)%0A
+@AutoConfigureAfter(WebConfigurer.class)%0A
 public c
@@ -1812,19 +1812,16 @@
 ntext);%0A
-%09%09%0A
 %09%09return
@@ -1920,19 +1920,185 @@
  Mappers
-%22);
+ using %7B%7D%22, beanFactory.getClass().getName());%0A%09%09logger.debug(%22Alternatively: %7B%7D%22,((HierarchicalBeanFactory)beanFactory).getParentBeanFactory().getClass().getName());%0A%09%09
 %0A%09%09Colle
@@ -2183,13 +2183,8 @@
 ors(
-this.
 bean
@@ -2867,19 +2867,16 @@
 LDS) );%0A
-%09%09%0A
 %09%09mapper

Add information about beanFactory being used, to debug failure to find com.fasterxml.jackson.databind.type.TypeFactory