package com.yihu.hos.config;

import com.yihu.hos.interceptor.AuditInterceptor;
import com.yihu.hos.standard.match.dictionary.DictitemStandardExistStrategy;
import com.yihu.hos.standard.match.metadata.MetatdataStandardExistStrategy;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.zbus.broker.ZbusBroker;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Locale;
import java.util.Properties;

/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2016/8/5.
 */
@Configuration
@EnableTransactionManagement
@ComponentScan("com.yihu.hos")
//@ImportResource({"classpath:spring/applicationContext.xml"}) //applicationContext相关bean创建
public class BeanConfig {

    @Autowired
    private DataSource dataSource;

    @Value("${hos.zbus.url}")
    private String zbusUrl;
    private ZbusBroker zbusBroker;

    @Value("${hos.filesystem.url}")
    private String fsUrl;

    @Bean
    public ZbusBroker getZbusBroker() {
        try {
            zbusBroker = new ZbusBroker(zbusUrl);
            return zbusBroker;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getZbusUrl() {
        return zbusUrl;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
        localSessionFactoryBean.setDataSource(this.dataSource);
        Properties properties1 = new Properties();
        properties1.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        properties1.setProperty("hibernate.show_sql", "false");
        properties1.setProperty("hibernate.format_sql", "true");
        localSessionFactoryBean.setHibernateProperties(properties1);
        localSessionFactoryBean.setPackagesToScan("com.yihu.hos.*.model");
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource("resource/");
        localSessionFactoryBean.setMappingDirectoryLocations(resource);
        //设置拦截器
        localSessionFactoryBean.setEntityInterceptor(this.auditInterceptor());
        return localSessionFactoryBean;
    }

    //txManager事务开启
    @Bean
    public HibernateTransactionManager txManager() throws SQLException {
        HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager();
        LocalSessionFactoryBean sessionFactoryBean = this.sessionFactory();
        hibernateTransactionManager.setSessionFactory(sessionFactoryBean.getObject());
        return hibernateTransactionManager;
    }

    //文经上传
    @Bean
    public CommonsMultipartResolver multipartResolver() {
        return new CommonsMultipartResolver();
    }

    //国际化配置
    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasenames("text/message");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    public CookieLocaleResolver localeResolver() {
        CookieLocaleResolver localeResolver = new CookieLocaleResolver();
        localeResolver.setCookieName("Language");
        localeResolver.setCookieMaxAge(604800);
        localeResolver.setDefaultLocale(new Locale("zh_cn"));
        return localeResolver;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        return new LocaleChangeInterceptor();
    }

    @Bean
    public JdbcTemplate jdbcTemplate() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        try {
            jdbcTemplate.setDataSource(this.dataSource);
            jdbcTemplate.setLazyInit(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jdbcTemplate;
    }

    //Hibernate模版配置
    @Bean
    public HibernateTemplate hibernateTemplate() throws SQLException {
        HibernateTemplate hibernateTemplate = new HibernateTemplate();
        LocalSessionFactoryBean sessionFactory = this.sessionFactory();
        hibernateTemplate.setSessionFactory(sessionFactory.getObject());
        return hibernateTemplate;
    }

    @Bean
    public AuditInterceptor auditInterceptor() {
        return new AuditInterceptor();
    }

    @Override
    protected void finalize() throws Throwable {
        if (zbusBroker != null) {
            zbusBroker.close();
        }

        super.finalize();
    }

    public String getFsUrl() {
        return fsUrl;
    }

    @Bean
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(5);
        threadPoolTaskExecutor.setMaxPoolSize(10);
        threadPoolTaskExecutor.setQueueCapacity(25);
        threadPoolTaskExecutor.setKeepAliveSeconds(300);
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return threadPoolTaskExecutor;
    }
    @Bean
    public MetatdataStandardExistStrategy metatdataStandardExistStrategy() {
        return new MetatdataStandardExistStrategy();
    }

    @Bean
    public DictitemStandardExistStrategy dictitemStandardExistStrategy() {
        return new DictitemStandardExistStrategy();
    }
}
