package sgc.portal.base.web;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.context.ConfigurableWebApplicationContext;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Java(POJO)에서 프러퍼티 파일을 사용하기 위한 초기화 클래스.
 *
 * @author YHKIM
 * @version 1.0.0
 * @since 2020. 4. 15.
 */
@Slf4j
class PropertySourcesApplicationContextInitializer
        implements ApplicationContextInitializer<ConfigurableWebApplicationContext> {/**
     * <pre>
     * web.xml에 선언된 spring.profiles.active 값을 참조하여 서버프로그램에서 DB 프로퍼티값을
     * 사용할수 있도록 함.
     * </pre>
     *
     * @param applicationContext
     */
    @Override
    public void initialize(ConfigurableWebApplicationContext applicationContext) {
        try{
            ConfigurableEnvironment environment = applicationContext.getEnvironment();
            String location = "/META-INF/properties/db-properties-local.xml";
//            현재 구성상 local 환경에서만 db-properties-local.xml을 사용하므로 아래 코드를 주석처리. yongsang  2020.07.25
//            if(activeProfiles[0].equals("local")){
//                location = "/META-INF/properties/db-properties-local.xml";
//            }else if(activeProfiles[0].equals("prd")){
//                location = "/META-INF/properties/db-properties-prd.xml";
//            }
            MutablePropertySources propertySources = environment.getPropertySources();

            List<Resource> resources = new ArrayList<>();
            resources.add(new ClassPathResource(location));

            PropertiesFactoryBean bean = new PropertiesFactoryBean();
            bean.setLocations(resources.toArray(new Resource[0]));
            bean.afterPropertiesSet();

            propertySources.addLast(new PropertiesPropertySource("dbProps", Objects.requireNonNull(bean.getObject())));

            log.info("========== Property Initializer Start ===========");
            log.info(" {} ", propertySources.get("dbProps"));
            log.info("========== Property Initializer End ===========");
        }catch(IOException e) {
            throw new ApplicationContextException("초기화에 실패하였습니다.", e);
        }

    }

    /*@Override
    public final void initialize(final ConfigurableWebApplicationContext applicationContext) {
        String activeProfileName = null;
        String location = null;
        try {
            ConfigurableEnvironment environment = applicationContext.getEnvironment();
            String[] activeProfiles = environment.getActiveProfiles();

            for (int i = 0; i < activeProfiles.length; i++) {
                activeProfileName = activeProfiles[i];

                location = "classpath:/META-INF/properties/db-properties-" + activeProfileName + ".xml";

                MutablePropertySources propertySources = environment.getPropertySources();
                addPropertySource(applicationContext, activeProfileName, location, propertySources);
                // LOGGER내 CRLF 공격 방지
                activeProfileName = activeProfileName.replaceAll("(\r\n|\n\r|\r|\n)", "");
                String cleanEnvironment = environment.getProperty("security.enc.key").replaceAll("(\r\n|\n\r|\r|\n)", "");
                log.info("profile : {}, key: {}", activeProfileName, cleanEnvironment);
            }

        } catch (IOException e) {
            // it's ok if the file is not there. we will just log that info.
            log.info("didn't find database_properties in classpath so not loading it in the AppContextInitialized");
        }
    }*/

    /*private void addPropertySource(final ConfigurableWebApplicationContext applicationContext,
            final String activeProfileName, final String location, final MutablePropertySources propertySources)
            throws IOException {
        Resource resource = applicationContext.getResource(location);
        if (resource.exists()) {
            ResourcePropertySource propertySource = new ResourcePropertySource(location);
            // propertySources.addFirst(new
            // ResourcePropertySource("classpath*:/properties/constant.xml"));
            propertySources.addLast(propertySource);
        } else {
            // LOGGER내 CRLF 공격 방지
            String removeCrlfActiveProfileName = activeProfileName.replaceAll("\n", "").replaceAll("\r", "");
            String removeCrlfLocation = location.replaceAll("\n", "").replaceAll("\r", "");
            log.info("could not find properties file for active Spring profile '{}' (tried '{}')",
                    removeCrlfActiveProfileName, removeCrlfLocation);
        }
    }*/
}
