package com.qy.worksheetsystem.config;

import com.alibaba.druid.filter.logging.Slf4jLogFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.sql.DataSource;
import java.util.*;

import com.alibaba.druid.filter.Filter;
import org.springframework.context.annotation.Scope;

/** /druid/spring.html
 * description: DruidConfig <br>
 * date: 9/12/2022 上午11:51 <br>
 * author: lhbj <br>
 * version: 1.0 <br>
 */
@Configuration
public class DruidConfig {
    /**
     * spring监控
     * @return
     */
    @Bean
    public DruidStatInterceptor druidStatInterceptor() {
        DruidStatInterceptor dsInterceptor = new DruidStatInterceptor();
        return dsInterceptor;
    }
    @Bean
    @Scope("prototype")
    public JdkRegexpMethodPointcut druidStatPointcut() {
        JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
        pointcut.setPatterns("com.qy.worksheetsystem.model.*","com.qy.worksheetsystem.service.*");
        return pointcut;
    }
    @Bean
    public DefaultPointcutAdvisor druidStatAdvisor(DruidStatInterceptor druidStatInterceptor, JdkRegexpMethodPointcut druidStatPointcut) {
        DefaultPointcutAdvisor defaultPointAdvisor = new DefaultPointcutAdvisor();
        defaultPointAdvisor.setPointcut(druidStatPointcut);
        defaultPointAdvisor.setAdvice(druidStatInterceptor);
        return defaultPointAdvisor;
    }
    /*
     * spring end
     */

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource getMyDruidDataSource(){
        DruidDataSource druidDataSource = new  DruidDataSource();
        List<Filter> filterList = druidDataSource.getProxyFilters();
        filterList.add(statFilter());
        filterList.add(wallFilter(wallConfig()));
        filterList.add(logFilter());

        //druidDataSource.setProxyFilters(filterList);
        return druidDataSource;
    }

    //配置Druid的监控
    //1.配置一个管理后台的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        // 记得加上"/druid/*",否则在进行登录页面的重定向过多而无法访问的问题(记得在Google浏览器才会报这个错)
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*");
        Map<String,String> initParams = new HashMap<>();

        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","admin");
        //默认是允许所有访问
        //initParams.put("allow","");
//        initParams.put("deny","192.168.31.30");
        bean.setInitParameters(initParams);
        return bean;
    }
    //2.配置一个web监控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());

        Map<String,String> initParams = new HashMap<>();
        //配置拦截时需要排除的请求
        initParams.put("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        bean.setInitParameters(initParams);

        bean.setUrlPatterns(Arrays.asList("/*"));

        return bean;

    }
//
//    @Bean(name = "wallConfig")
//    public WallConfig wallFilterConfig() {
//        WallConfig wc = new WallConfig();
//        wc.setMultiStatementAllow(true);//允许一次执行多条语句
//        wc.setNoneBaseStatementAllow(true);
//        return wc;
//    }
//
//    @Bean(name = "wallFilter")
//    @DependsOn("wallConfig")
//    public WallFilter wallFilter(WallConfig wallConfig) {
//
//        WallFilter wfilter = new WallFilter();
//        wfilter.setConfig(wallConfig);
//        return wfilter;
//    }
    @Bean
    public Slf4jLogFilter logFilter () {
        Slf4jLogFilter logFilter = new Slf4jLogFilter();
        logFilter.setStatementExecutableSqlLogEnable(true);
        logFilter.setStatementLogEnabled(false);
        return logFilter;
    }
    @Bean
    public StatFilter statFilter () {
        StatFilter statFilter = new StatFilter();
        statFilter.setSlowSqlMillis(3000);
        statFilter.setLogSlowSql(true);
        statFilter.setMergeSql(true);
        return statFilter;
    }
    /**
     * sql防火墙过滤器配置
     * @param wallConfig
     * @return
     */
    @Bean
    public WallFilter wallFilter (WallConfig wallConfig) {
        WallFilter wallFilter = new WallFilter();
        wallFilter.setConfig(wallConfig);
        wallFilter.setLogViolation(true);//对被认为是攻击的SQL进行LOG.error输出
        wallFilter.setThrowException(false);//对被认为是攻击的SQL抛出SQLException
        return wallFilter;
    }
    /**
     * sql防火墙配置
     * @return
     */
    @Bean
    public WallConfig wallConfig () {
        WallConfig wallConfig = new WallConfig();
        wallConfig.setAlterTableAllow(false);
        wallConfig.setCreateTableAllow(false);
        wallConfig.setDeleteAllow(false);
        wallConfig.setMergeAllow(false);
        wallConfig.setDescribeAllow(false);
        wallConfig.setShowAllow(false);
        wallConfig.setMultiStatementAllow(true);//允许一次执行多条语句
        wallConfig.setNoneBaseStatementAllow(true);
        return wallConfig;
    }
}
