package cn.quantgroup.xyqb.config;

import cn.quantgroup.xyqb.security.AuthenticationAdapter;
import cn.quantgroup.xyqb.security.AuthenticationPrincipal;
import cn.quantgroup.xyqb.security.CustomerAuthenticationManager;
import cn.quantgroup.xyqb.urora.UroraAuthenticationManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Properties;
import java.util.Set;

import static cn.quantgroup.xyqb.security.SecurityConstant.PROPERTY_PREFIX;

/**
 * Created by Administrator on 2021/7/1 0001.
 */
@Configuration
@EnableConfigurationProperties(AuthenticationConfigurationProperties.class)
public class AuthenticationConfiguration {
    private static final Logger logger = LoggerFactory.getLogger(AuthenticationConfiguration.class);

    @Bean
    public AuthenticationAdapter authenticationAdapter(AuthenticationConfigurationProperties properties) {
        AuthenticationAdapter adapter = new AuthenticationAdapter();
        Map<String, Map<String, String>> manager = properties.getManager();
        Set<String> strings = manager.keySet();
        try {
            for (String key : strings) {
                Map<String, String> map = manager.get(key);

                Class<?> target = Thread.currentThread().getContextClassLoader().loadClass(map.get("target"));
                //TODO: wait bean bean definition authentication manager
                CustomerAuthenticationManager instance = (CustomerAuthenticationManager) target.newInstance();
                instance.setPrincipal(new AuthenticationPrincipal(key));

                Properties prop = new Properties();
                map.forEach((k, v) -> {
                    if (k.startsWith(PROPERTY_PREFIX)) {
                        prop.setProperty(k.substring(PROPERTY_PREFIX.length()), v);
                    }
                });
                instance.setProperties(prop);

                if (UroraAuthenticationManager.class.isInstance(instance)) {
                    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
                    factory.setReadTimeout(Integer.parseInt(prop.getProperty("readTimeout", "10000")));
                    factory.setConnectTimeout(Integer.parseInt(prop.getProperty("connectTimeout", "20000")));
                    RestTemplate restTemplate = new RestTemplate();
                    restTemplate.setRequestFactory(factory);
                    ((UroraAuthenticationManager) instance).setRestTemplate(restTemplate);
                }
                instance.init();
                logger.info("Authentication adapter register manager. {} - properties:{}", target, prop);
                adapter.register(instance);
            }
        } catch (Exception e) {
            logger.error("Authentication configuration initialization failed. " + e.getMessage(), e);
        }

        return adapter;
    }
}
