package com.qmth.boot.mybatis.config;

import ch.qos.logback.classic.Level;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusPropertiesCustomizer;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.qmth.boot.core.constant.CoreConstant;
import com.qmth.boot.core.logger.context.LoggerContextService;
import com.qmth.boot.mybatis.logger.MybatisPlusLogger;
import com.qmth.boot.mybatis.plugin.MybatisProfilerPlugin;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.validation.constraints.NotNull;

/**
 * MyBatisPlus插件配置
 */
@Configuration
@ComponentScan("com.qmth.boot.mybatis")
public class MybatisPlusAutoConfiguration {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(@NotNull MybatisProperties mybatisProperties,
            @NotNull DataSourceProperties dataSourceProperties) {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(getDbType(dataSourceProperties)));
        if (mybatisProperties.isBlockAttack()) {
            interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        }
        return interceptor;
    }

    @Bean
    public MybatisPlusPropertiesCustomizer plusPropertiesCustomizer() {
        return plusProperties -> plusProperties.getGlobalConfig().setBanner(false);
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer(@NotNull LoggerContextService loggerContextService,
            @NotNull MybatisProperties mybatisProperties) {
        return configuration -> {
            loggerContextService.setLevel(MybatisPlusLogger.class, Level.toLevel(mybatisProperties.getLogLevel()));
            configuration.setLogImpl(MybatisPlusLogger.class);
        };
    }

    private DbType getDbType(DataSourceProperties dataSourceProperties) {
        String driverClassName = dataSourceProperties.getDriverClassName();
        if (driverClassName.contains(DbType.MYSQL.getDb())) {
            return DbType.MYSQL;
        } else {
            return DbType.OTHER;
        }
    }

    @Bean
    @ConditionalOnProperty(value = CoreConstant.CONFIG_PREFIX + ".mybatis.profiler.enable", havingValue = "true")
    public MybatisProfilerPlugin mybatisProfilerPlugin(@NotNull MybatisProperties mybatisProperties) {
        return new MybatisProfilerPlugin(mybatisProperties.getProfiler());
    }
}
