package com.trade.common.config.mybatis;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusPropertiesCustomizer;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.extension.MybatisMapWrapperFactory;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.trade.common.utils.DataScopeContext;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

/**
 * mp 配置
 * reference https://baomidou.com/
 */
@Configuration
public class MybatisPlusConfig {

    /**
     * 分页插件
     */
    @Bean
    @Order(Ordered.LOWEST_PRECEDENCE-1)
    public MybatisPlusInterceptor mybatisPlusInterceptor(DataPermissionHandler dataPermissionHandler) {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 如果用了分页插件注意先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
        //TODO OR Page Helper ？
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        interceptor.addInnerInterceptor(new DataPermissionInterceptor(dataPermissionHandler));
        return interceptor;
    }

    /**
     * 开启返回map结果集的下划线转驼峰
     *
     * @return
     */
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return i -> i.setObjectWrapperFactory(new MybatisMapWrapperFactory());
    }

    @Bean
    public MybatisPlusPropertiesCustomizer plusPropertiesCustomizer() {
        return plusProperties -> plusProperties.getGlobalConfig().setIdentifierGenerator(new DefaultIdentifierGenerator());
    }

    /**
     * 数据权限插件处理器
     *
     * @return
     */
    @Bean
    public DataPermissionHandler dataPermissionHandler() {
        return (where, mappedStatementId) -> {
            String permissionSql = DataScopeContext.getPermissionSql();
            if (StringUtils.isBlank(permissionSql)) {
                return null;
            }
            try {
                Expression sqlSegmentExpression = CCJSqlParserUtil.parseCondExpression(permissionSql);
                if (null != where) {
                    return new AndExpression(where, sqlSegmentExpression);
                }
                return sqlSegmentExpression;
            } catch (JSQLParserException e) {
                e.printStackTrace();
            }
            return null;
        };
    }

}
