package com.artfess.base.conf;

import com.artfess.base.constants.TenantConstant;
import com.artfess.base.filter.ClobDataResultSetFilter;
import com.artfess.base.filter.FormDataResultSetFilter;
import com.artfess.base.handler.MultiTenantHandler;
import com.artfess.base.id.MybatisPlusIdGenerator;
import com.artfess.base.interceptor.DataPermissionInterceptor;
import com.artfess.base.interceptor.MasterSlaveAutoRoutingPlugin;
import com.artfess.base.interceptor.ResultSetInterceptor;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;


/**
 * mybatis配置类
 *
 * @company 阿特菲斯信息技术有限公司
 * @author heyifan
 * @email heyf@jee-soft.cn
 * @date 2020年3月30日
 */
@Configuration
public class MybatisPlusConfig {
	@Autowired
	MultiTenantHandler myTenantHandler;
	@Autowired
	SaaSConfig saaSConfig;

//	@Bean
//	public MybatisPlusInterceptor mybatisPlusInterceptor() {
//		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//		//数据库类型是MySql，因此参数填写DbType.MYSQL
//		interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//		//添加乐观锁插件
//		interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
//		return interceptor;
//	}


	/**
	 * 数据权限拦截器
	 * @return
	 */
	@Bean
	public Interceptor getInterceptor(){
		return new DataPermissionInterceptor();
	}


	/**
	 * 返回结果处理拦截器
	 * @return
	 */
	@Bean
	public Interceptor getResultSetInterceptor() {
		ResultSetInterceptor resultSetInterceptor = new ResultSetInterceptor();
		FormDataResultSetFilter formDataResultSetFilter = new FormDataResultSetFilter();
		// clob 数据格式化处理
		ClobDataResultSetFilter clobDataResultSetFilter = new ClobDataResultSetFilter();
		resultSetInterceptor.addFilters(formDataResultSetFilter);
		resultSetInterceptor.addFilters(clobDataResultSetFilter);
		return resultSetInterceptor;
	}

	/**
	 * 自定义ID生成器
	 * @return
	 */
	@Bean
	public IdentifierGenerator identifierGenerator() {
		return new MybatisPlusIdGenerator();
	}

	/**
	 * 多租户拦截器
	 * @return
	 */
	@Bean
	public PaginationInterceptor paginationInterceptor() {
		PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
		//支持oceanbase分页
		paginationInterceptor.setDialectType(DbType.MYSQL.getDb());
		// SQL解析处理拦截：增加租户处理回调。
		List<ISqlParser> sqlParserList = new ArrayList<>();
		// 攻击 SQL 阻断解析器、加入解析链
//		sqlParserList.add();

		// 开启多租户模式
		if(saaSConfig.isEnable()) {
			myTenantHandler.setTenantId(saaSConfig.getTenantId());
			List<String> ignoreTables = saaSConfig.getIgnoreTables();
			ignoreTables.addAll(TenantConstant.IGNORE_TABLES);
			myTenantHandler.setIgnoreTableNames(ignoreTables);

			// 多租户拦截
			TenantSqlParser tenantSqlParser = new TenantSqlParser();
			tenantSqlParser.setTenantHandler(myTenantHandler);
			sqlParserList.add(tenantSqlParser);
		}
		paginationInterceptor.setSqlParserList(sqlParserList);
		return paginationInterceptor;
	}

	/**
	 * 读写分离的主从数据库
	 * @return
	 */
	@Bean
	public MasterSlaveAutoRoutingPlugin masterSlaveAutoRoutingPlugin(){
		return new MasterSlaveAutoRoutingPlugin();
	}

	@Bean
	public OptimisticLockerInterceptor optimisticLockerInterceptor() {
		return new OptimisticLockerInterceptor();
	}

	/**
	 * 方言类型识别器
	 * @return
	 */
	@Bean
	public DatabaseIdProvider databaseIdProvider() {
		VendorDatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
		Properties properties = new Properties();
		// 在mapper中标注databaseId="mysql"则表示该sql仅支持MySQL数据库
		properties.put("Oracle","oracle");
		properties.put("MySQL","mysql");
		properties.put("H2","h2");
		properties.put("SQLServer","sqlserver");
		properties.put("PostgreSQL","pg");
		properties.put("DM DBMS","oracle");
		databaseIdProvider.setProperties(properties);
		return databaseIdProvider;
	}
}
