package eu.bcvsolutions.idm.core.config;

import static eu.bcvsolutions.idm.core.api.service.ConfigurationService.IDM_PRIVATE_PROPERTY_PREFIX;
import static eu.bcvsolutions.idm.core.api.service.ConfigurationService.PROPERTY_SEPARATOR;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import eu.bcvsolutions.idm.core.api.domain.CoreResultCode;
import eu.bcvsolutions.idm.core.api.exception.ResultCodeException;
import eu.bcvsolutions.idm.core.api.service.ConfigurationService;

/**
 * Configuration beans required for rest communication with ReCaptcha services.
 * 
 * @author Filip Mestanek
 */
@Configuration
public class RestTemplateConfig {
	
	private static final Logger LOG = LoggerFactory.getLogger(RestTemplateConfig.class);
	private static final String PROXY_KEY = IDM_PRIVATE_PROPERTY_PREFIX + "core" + PROPERTY_SEPARATOR + "http" + PROPERTY_SEPARATOR + "proxy";
	
	@Autowired private ConfigurationService configuration;
	
	
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory httpRequestFactory) {
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
        return restTemplate;
    }
    
    /**
     * Returns proxy to use for http requests. If no proxy is set, returns null.
     */
    public Proxy getHttpProxy() {
    	String proxyConfig = configuration.getValue(PROXY_KEY, null);
    	if (!StringUtils.hasText(proxyConfig)) {
    		return null;
    	}
    	
		LOG.debug("Configuring proxy {}", proxyConfig);

		String[] split = proxyConfig.split(":");
		if (split.length != 2) {
			throw new ResultCodeException(CoreResultCode.WRONG_PROXY_CONFIG);
		}

		String host = split[0];
		int port;
		try {
			port = Integer.parseInt(split[1]);
		} catch (NumberFormatException ex) {
			throw new ResultCodeException(CoreResultCode.WRONG_PROXY_CONFIG);
		}

		return new Proxy(Type.HTTP, new InetSocketAddress(host, port));
    }

    @Bean
    public ClientHttpRequestFactory httpRequestFactory(HttpClient httpClient) {
		SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();

		Proxy proxy = getHttpProxy();
		if (proxy != null) {
			requestFactory.setProxy(proxy);
		}

		return requestFactory;
    }

    @Bean
    public HttpClient httpClient() {
        return HttpClientBuilder.create().build();
    }
}

@@ -532,16 +532,82 @@
 owired;%0A
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;%0A
 import o
@@ -650,16 +650,16 @@
 n.Bean;%0A
-
 import o
@@ -707,24 +707,81 @@
 figuration;%0A
+import org.springframework.context.annotation.DependsOn;%0A
 import org.s
@@ -1277,16 +1277,80 @@
 Service;
+%0Aimport eu.bcvsolutions.idm.core.config.flyway.CoreFlywayConfig;
 %0A%0A/**%0A *
@@ -1476,16 +1476,50 @@
 uration%0A
+@DependsOn(CoreFlywayConfig.NAME)%0A
 public c
@@ -1832,18 +1832,16 @@
 tion;%0A%09%0A
-%09%0A
     @Bea
@@ -2229,16 +2229,16 @@
      */%0A
-
     publ
@@ -2259,24 +2259,286 @@
 tpProxy() %7B%0A
+    %09// TODO: proxy is initialized on application start - configuration can be changed by server restart only, possible solutions:%0A    %09// - change configuration key - without idm. prefix and edit doc%0A    %09// - try to construct proxy dynamically (request scope)%0A
     %09String 

change rest template init order