package com.cesgroup.Interceptor;

import com.cesgroup.util.ReflectHelper;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.type.TypeHandlerRegistry;
import sun.plugin2.main.server.ResultHandler;

import javax.security.auth.login.Configuration;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

@Intercepts({@Signature(type = StatementHandler.class,method = "query",args = {Statement.class, ResultHandler.class})})
public class MybatisLogInterceptor implements Interceptor{

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Logger logger = null;
        String sql = null;
       if (invocation.getTarget() instanceof RoutingStatementHandler) {
           RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation.getTarget();
           StatementHandler delegate = (StatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate");
           BoundSql boundSql = delegate.getBoundSql();
           Object parameterObject = boundSql.getParameterObject();
           List<Object> params = new ArrayList<>();
           TypeHandlerRegistry typeHandlerRegistry = (TypeHandlerRegistry) ReflectHelper.getValueByFieldName(delegate, "typeHandlerRegistry");
           Configuration configuration = ReflectHelper.getFieldByFieldName(delegate, "configuration");
           List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
           if (parameterMappings != null) {
               for (int i = 0; i < parameterMappings.size(); i++) {
                   ParameterMapping parameterMapping = parameterMappings.get(i);
                   if (parameterMapping.getMode() != ParameterMode.OUT) {
                       Object value = null;
                       String propertyName = parameterMapping.getProperty();
                       if (boundSql.hasAdditionalParameter(propertyName)) {
                           value = boundSql.getAdditionalParameter(propertyName);
                       } else if (parameterObject == null) {
                           value = null;
                       } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                           value = parameterObject;
                       }
                       params.add(value);
                   }
               }
           }
            sql = boundSql.getSql();
           for (Object param : params) {
               sql = sql.replaceFirst("[?]]", param + "");
           }
       }
           return sql;
    }

    @Override
    public Object plugin(Object o) {
        return null;
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
