package com.liangjian.dataplatform.member.config;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Lists;
//import com.liangjian.dataplatform.member.algorithm.TableShardingAlgorithm;
//import io.shardingsphere.core.yaml.sharding.YamlShardingConfiguration;
//import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
//import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
//import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
//import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
//import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;

/**
 * @Author: 黄子奇
 * @Date: 2019/12/5
 *
 * 目前分表已由es代替，不再使用
 */

//@Configuration
//@EnableTransactionManagement
//@EnableJpaRepositories(
//        entityManagerFactoryRef="entityManagerFactorySubtables",
//        transactionManagerRef="transactionManagerSubtables",
//        basePackages= { "com.liangjian.dataplatform.member.dao.subtables" })
@Deprecated
public class DBSubtablesConfig {
//    @Autowired
    private Filter statFilter;

    private static final String SHARDING_YML_PATH = "sharding/dataSource.yml";


//    @Autowired
    private HibernateProperties hibernateProperties;

//    @Autowired
//    @Qualifier("subtablesDataSource")
    private DataSource subtablesDataSource;
//
//    /**
//     * 构建dataSource
//     * 这里没有使用ShardingDataSourceFactory
//     * 因为要为durid数据源配置监听Filter
//     * @return
//     * @throws SQLException
//     * @throws IOException
//     */
//    @Bean
//    public DataSource dataSource() throws SQLException, IOException {
//        YamlShardingConfiguration config = parse();
//        ShardingRule rule = config.getShardingRule(Collections.<String>emptyList());
//        rule.shardingDataSourceNames().forEach((k,v)->{
//            DruidDataSource d = (DruidDataSource) v;
//            d.setProxyFilters(Lists.newArrayList(statFilter));
//        });
//        return new ShardingDataSource(rule, config.getShardingRule().getConfigMap(), config.getShardingRule().getProps());
//    }

    /**
     * 解析yml
     * @return
     * @throws IOException
     * @throws FileNotFoundException
     * @throws UnsupportedEncodingException
     */
//    private YamlShardingConfiguration parse() throws IOException, FileNotFoundException, UnsupportedEncodingException {
//        Resource certResource = new ClassPathResource(SHARDING_YML_PATH);
//        try (
//                InputStreamReader inputStreamReader = new InputStreamReader(certResource.getInputStream(), "UTF-8")
//        ) {
//            return new Yaml(new Constructor(YamlShardingConfiguration.class)).loadAs(inputStreamReader, YamlShardingConfiguration.class);
//        }
//    }

//    @Bean(name = "entityManagerSubtables")
//    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
//        return entityManagerFactorySubtables(builder).getObject().createEntityManager();
//    }

//    @Bean(name = "entityManagerFactorySubtables")
//    public LocalContainerEntityManagerFactoryBean entityManagerFactorySubtables (EntityManagerFactoryBuilder builder) {
//        //这里直接不走yml配置，直接在这里配置上去
//        JpaProperties jpaProperties = new JpaProperties();
//
//        //配置表映射的命名规则，不做任何改变，原来的是遇到大写就变小写和下划线
//        hibernateProperties.getNaming().setPhysicalStrategy("org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
//        Map<String, Object> properties = hibernateProperties.determineHibernateProperties(
//                jpaProperties.getProperties(), new HibernateSettings());
//
//        LocalContainerEntityManagerFactoryBean factoryBean = builder
//                .dataSource(getShardingDataSource())
//                .properties(properties)
//                .packages("com.liangjian.dataplatform.member.entity.po.subtables")
//                .persistenceUnit("subtablesPersistenceUnit")
//                .build();
//        factoryBean.setJpaProperties(jpaProperties());
//        factoryBean.setJpaVendorAdapter(vendorAdaptor());
//        return factoryBean;
//    }

    //分库分表配置
//    private DataSource getShardingDataSource() {
//        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
//
//        TableRuleConfiguration userPointLog = new TableRuleConfiguration("mem_user_point_log","ds0.mem_user_point_log$->{0..2}");
//        TableRuleConfiguration userGrowthLog = new TableRuleConfiguration("mem_user_growth_log","ds0.mem_user_growth_log$->{0..2}");
//
//        shardingRuleConfig.getTableRuleConfigs().add(userPointLog);
//        shardingRuleConfig.getTableRuleConfigs().add(userGrowthLog);
//        shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "ds0"));
//        shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("id", new TableShardingAlgorithm()));
//
//        Map<String,DataSource> dataSourceMap = Map.of("ds0",subtablesDataSource);
//        try {
//            return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());
//        } catch (Exception ex) {
//            throw new RuntimeException(ex);
//        }
//    }

    private Properties jpaProperties() {
        Properties properties = new Properties();
        properties.put("database-platform","org.hibernate.dialect.SQLServer2012Dialect");
        properties.put("show-sql","true");
        properties.put("open-in-view","true");
        properties.put("hibernate.hbm2ddl.auto", "none");
        return properties;
    }

    private HibernateJpaVendorAdapter vendorAdaptor() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setDatabasePlatform("org.hibernate.dialect.SQLServer2012Dialect");
        vendorAdapter.setShowSql(true);
        return vendorAdapter;
    }

//    @Bean(name = "transactionManagerSubtables")
//    PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
//        return new JpaTransactionManager(entityManagerFactorySubtables(builder).getObject());
//    }
}
