package com.platform.config;

import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.parser.ISqlParser;
import com.baomidou.mybatisplus.plugins.parser.tenant.TenantHandler;
import com.baomidou.mybatisplus.plugins.parser.tenant.TenantSqlParser;
import com.platform.modules.app.interceptor.AuthorizationInterceptor;
import com.platform.modules.live.utils.PlatformTenantProperties;
import com.platform.modules.sys.entity.SysUserEntity;
import com.platform.modules.sys.service.SysSchemaService;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * mybatis-plus配置
 *
 * @author TONG
 */
@Configuration
public class MybatisPlusConfig implements ApplicationRunner {

    Logger logger = LoggerFactory.getLogger(MybatisPlusConfig.class);

    private Set<String> tables = new HashSet<>();

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private PlatformTenantProperties properties;
    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();

        TenantSqlParser tenantSqlParser = new MybatisTenantParser(properties);
        List<ISqlParser> sqlParserList = new ArrayList<>();
        tenantSqlParser.setTenantHandler(new TenantHandler() {
            private Expression singleTenantIdCondition() {
                try {
                    Object principal = SecurityUtils.getSubject().getPrincipal();
                    if (principal != null) {
                        SysUserEntity sysUserEntity = (SysUserEntity) principal;
                        if (sysUserEntity.getTenantId() != null)
                            return new LongValue(sysUserEntity.getTenantId());
                    } else {
                        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
                        Object tenantId = requestAttributes.getAttribute(AuthorizationInterceptor.USER_TENANT_KEY, RequestAttributes.SCOPE_REQUEST);
                        if (tenantId != null)
                            return new LongValue(tenantId.toString());
                    }
                } catch (Exception e) {//处理定时任务
                    logger.warn("未登录获取不到 SecurityManager {}", e.getMessage());
                }
                return null;
            }

//            private Expression multipleTenantIdCondition() {
//                final InExpression inExpression = new InExpression();
//                inExpression.setLeftExpression(new Column(getTenantIdColumn()));
//                final ExpressionList itemsList = new ExpressionList();
//                final List<Expression> inValues = new ArrayList<>(2);
//                inValues.add(new LongValue(1));//ID自己想办法获取到
//                inValues.add(new LongValue(2));
//                itemsList.setExpressions(inValues);
//                inExpression.setRightItemsList(itemsList);
//                return inExpression;
//            }

            @Override
            public Expression getTenantId() {
                return singleTenantIdCondition();
            }

            @Override
            public String getTenantIdColumn() {
                return properties.getColumnName();
            }

            @Override
            public boolean doTableFilter(String tableName) {

                return !tables.contains(tableName.toLowerCase());
            }

        });

        sqlParserList.add(tenantSqlParser);
        paginationInterceptor.setSqlParserList(sqlParserList);

        return paginationInterceptor;
    }

    @Override
    public void run(ApplicationArguments applicationArguments)  {
        SysSchemaService sysSchemaService = applicationContext.getBean(SysSchemaService.class);
        List<String> tableNames = sysSchemaService.queryTableNames(properties.getColumnName());
        tables.addAll(tableNames);
    }
}
