package com.yizhi.application.aop;

import java.lang.reflect.Field;
import java.util.Set;

import com.yizhi.core.application.cache.CacheNamespace;
import com.yizhi.core.application.cache.RedisCache;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.util.application.json.JsonUtil;
import com.yizhi.util.application.sensitive.SensitivewordFilter;
import com.yizhi.util.application.sensitive.annotation.SensitiveWords;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;



/**
 * 过滤敏感词实现类
 * 根据企业ID获取缓存中的企业敏感词信息，根据敏感词过滤数据
 * @author mei
 *
 */
@Aspect
@Component
public class SensitiveWordsAspect {
	private static final Logger log = LoggerFactory.getLogger(SensitiveWordsAspect.class);
	
	@Autowired
    private RedisCache redisCache;
	
	/**
	 * 拦截包下所有的方法
	 */
	@Pointcut("execution(* com.yizhi..*.*(..))")
	public void pointcut() {
	}

	/**
	 * 拦截有@SensitiveWords注解的方法
	 * @param point
	 * @param sensitiveWords
	 */
	@Before(value = "pointcut() && @annotation(sensitiveWords)")
	public void sensitiveWords(JoinPoint point, SensitiveWords sensitiveWords) {
		try{
			log.info("敏感词过滤,开始");
			RequestContext requestContext = ContextHolder.get();
			if(requestContext == null){
				log.info("敏感词过滤失败,无法获取上下文信息");
				return;
			}
			
			Long companyId = requestContext.getCompanyId();
			if(companyId == null){
				log.info("敏感词过滤失败,无法获取企业ID");
				return;
			}
			
			String sensitiveValues = (String) redisCache.hget(CacheNamespace.REDIS_SENSITIVE_WORD_INFO, companyId.toString());
			if(sensitiveValues == null){
				log.info("敏感词过滤失败,无法获取企业敏感词信息");
				return;
			}
			@SuppressWarnings("unchecked")
			Set<String> sensitiveWordList = JsonUtil.json2Ojbect(sensitiveValues, Set.class);
			if(sensitiveWordList == null){
				log.info("敏感词过滤失败,无法获取企业敏感词信息");
				return;
			}
			
			Object args[] = point.getArgs();
			boolean isBask = false;
			for (Object arg : args) {
				Field fields[] = arg.getClass().getDeclaredFields();
				for (Field field : fields) {
					if(field.getType() == String.class){

						field.setAccessible(true); 
						String value = (String) field.get(arg);
						if(StringUtils.isBlank(value)){
							continue;
						}
						//过滤
						value = SensitivewordFilter.sensitiveFilter(value, sensitiveWordList);
						field.set(arg, value);
						isBask = true;
						break;
					/*
						SensitiveWords s = field.getAnnotation(SensitiveWords.class);
						if (s != null) {}*/
					}
				}
				
				if(isBask){
					break;
				}
			}
			
			log.info("敏感词过滤,结束");
		} catch(Exception e){
			log.info("敏感词过滤,失败");
			e.printStackTrace();
		}
	}
}