package gov.va.vss.config;

import java.io.File;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor;
import org.springframework.web.servlet.support.RequestDataValueProcessor;

import gov.va.shared.config.AbstractConfig;
import gov.va.shared.web.support.CompositeRequestDataValueProcessor;

@Configuration
@Import({ ScheduledTasksConfig.class, WebSecurityConfig.class })
@PropertySource("file:///${AppPropertiesDir:" + AbstractConfig.DEFAULT_APP_PROPERTIES_DIR + "}/app.properties")
@PropertySource("file:///${AppPropertiesDir:" + AbstractConfig.DEFAULT_APP_PROPERTIES_DIR + "}/version.properties")
public class WebAppConfig extends AbstractAppConfig {

	public static final String DEFAULT_WEB_MESSAGES_DIR = DEFAULT_BASEDIR + "/web/src/main/resources";

	@Value("${AppPropertiesDir:" + DEFAULT_WEB_MESSAGES_DIR + "}")
	private String messagesDir;
	@Value("${AppPropertiesDir:" + DEFAULT_APP_PROPERTIES_DIR + "}")
	private String propertiesDir;

	@Bean
	public MessageSource messageSource() {
		ReloadableResourceBundleMessageSource ms = new ReloadableResourceBundleMessageSource();
		ms.setCacheSeconds(Integer.parseInt(env.getProperty("messages.cache.expirySeconds")));
		ms.setBasenames("file:///" + messagesDir + File.separator + "messages",
				"file:///" + propertiesDir + File.separator + "app");
		return ms;
	}

	@Bean
	public static BeanDefinitionRegistryPostProcessor vssDataValueProcessorPostProcessor() {
		return new BeanDefinitionRegistryPostProcessor() {

			@Override
			public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
			}

			@Override
			public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
				RootBeanDefinition rdb = null;
				try {
					registry.removeBeanDefinition("requestDataValueProcessor");

					ConstructorArgumentValues cargs = new ConstructorArgumentValues();
					RequestDataValueProcessor[] arr = new RequestDataValueProcessor[] {
							new CsrfRequestDataValueProcessor(),
							new EnsureSingleSessionConversationRequestDataValueProcessor() };
					cargs.addGenericArgumentValue(arr);

					rdb = new RootBeanDefinition(CompositeRequestDataValueProcessor.class, cargs,
							new MutablePropertyValues());
				} catch (NoSuchBeanDefinitionException e) {
					rdb = new RootBeanDefinition(EnsureSingleSessionConversationRequestDataValueProcessor.class);
				}

				registry.registerBeanDefinition("requestDataValueProcessor", rdb);
			}
		};
	}

}
