package org.alien4cloud.bootstrap;

import java.io.IOException;

import javax.servlet.MultipartConfigElement;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration;
import org.springframework.boot.context.embedded.MultipartConfigFactory;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;

import alien4cloud.servlet.ImageServlet;
import alien4cloud.utils.AlienYamlPropertiesFactoryBeanFactory;

@Configuration("bootstrap-config")
@EnableAutoConfiguration(exclude = { HypermediaAutoConfiguration.class })
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(basePackages = { "org.alien4cloud.bootstrap", "alien4cloud.audit", "alien4cloud.security", "alien4cloud.webconfiguration",
        "org.alien4cloud.exception", "org.elasticsearch.mapping", "alien4cloud.dao", "alien4cloud.servlet", "alien4cloud.images" })
public class Bootstrap {

    /**
     * Alien 4 cloud standalone entry point.
     *
     * @param args Arguments that will be delegated to spring.
     */
    public static void main(String[] args) {
        configure();
        SpringApplication.run(Bootstrap.class, args);
    }

    public static void configure() {
        System.setProperty("security.basic.enabled", "false");
        System.setProperty("management.contextPath", "/rest/admin");
        System.setProperty("spring.config.name", AlienYamlPropertiesFactoryBeanFactory.ALIEN_CONFIGURATION);
    }

    @Bean(name = { "alienconfig", "elasticsearchConfig" })
    public static YamlPropertiesFactoryBean alienConfig(ResourceLoader resourceLoader) throws IOException {
        return AlienYamlPropertiesFactoryBeanFactory.get(resourceLoader);
    }

    @Bean
    public MultipartConfigElement multipartConfigElement(@Value("${upload.max_archive_size}") long maxUploadSize) {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setMaxRequestSize(maxUploadSize);
        factory.setMaxFileSize(maxUploadSize);
        return factory.createMultipartConfig();
    }

    @Bean
    public StandardServletMultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }

    @Bean
    public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet, MultipartConfigElement multipartConfig) {
        ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet);
        registration.addUrlMappings("/*");
        registration.setMultipartConfig(multipartConfig);
        registration.setAsyncSupported(true);
        return registration;
    }

    @Bean
    public ServletRegistrationBean imageRegistration(ImageServlet imageServlet) {
        ServletRegistrationBean registration = new ServletRegistrationBean(imageServlet);
        registration.addUrlMappings("/img/*");
        return registration;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        // this to avoid errors when properties are not resolvable
        // beans should use default value syntax to verify that the property exists
        // @Value("${some.key:#{null}}")
        configurer.setIgnoreUnresolvablePlaceholders(true);
        return configurer;
    }
}

@@ -56,16 +56,87 @@
 ception;
+%0Aimport java.net.Authenticator;%0Aimport java.net.PasswordAuthentication;
 %0A%0Aimport
@@ -1284,16 +1284,57 @@
 actory;%0A
+import lombok.extern.slf4j.Slf4j;%0A%0A@Slf4j
 %0A@Config
@@ -1973,24 +1973,64 @@
 onfigure();%0A
+        initializeProxyAuthenticator();%0A
         Spri
@@ -2074,24 +2074,643 @@
 gs);%0A    %7D%0A%0A
+    public static void initializeProxyAuthenticator() %7B%0A        final String proxyUser = System.getProperty(%22http.proxyUser%22);%0A        final String proxyPassword = System.getProperty(%22http.proxyPassword%22);%0A%0A        if (proxyUser != null && proxyPassword != null) %7B%0A            log.debug(%22Set http proxy credentials (%22 + proxyUser + %22)%22);%0A            Authenticator.setDefault(new Authenticator() %7B%0A                public PasswordAuthentication getPasswordAuthentication() %7B%0A                    return new PasswordAuthentication(proxyUser, proxyPassword.toCharArray());%0A                %7D%0A            %7D);%0A        %7D%0A    %7D%0A%0A
     public s
@@ -3222,32 +3222,511 @@
 Loader);%0A    %7D%0A%0A
+    @Bean%0A    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() %7B%0A        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();%0A        // this to avoid errors when properties are not resolvable%0A        // beans should use default value syntax to verify that the property exists%0A        // @Value(%22$%7Bsome.key:#%7Bnull%7D%7D%22)%0A        configurer.setIgnoreUnresolvablePlaceholders(true);%0A        return configurer;%0A    %7D%0A%0A
     @Bean%0A    pu
@@ -4888,486 +4888,7 @@
    %7D
-%0A%0A    @Bean%0A    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() %7B%0A        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();%0A        // this to avoid errors when properties are not resolvable%0A        // beans should use default value syntax to verify that the property exists%0A        // @Value(%22$%7Bsome.key:#%7Bnull%7D%7D%22)%0A        configurer.setIgnoreUnresolvablePlaceholders(true);%0A        return configurer;%0A    %7D
 %0A%7D%0A

Allow authentication on http proxy