
/**
 * 
 */
package org.tio.sitexxx.server.http.stat.token;

import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.TioConfig;
import org.tio.http.common.HttpRequest;
import org.tio.http.server.handler.DefaultHttpRequestHandler;
import org.tio.http.server.stat.token.TokenAccessStat;
import org.tio.http.server.stat.token.TokenPathAccessStat;
import org.tio.sitexxx.service.service.ConfService;
import org.tio.sitexxx.service.vo.Const;
import org.tio.sitexxx.server.http.WebApiHttpSessionListener;
import org.tio.utils.json.Json;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * @author tanyaowu
 *
 */
public class TioSiteTokenPathAccessStatListener implements org.tio.http.server.stat.token.TokenPathAccessStatListener {
	private static Logger log = LoggerFactory.getLogger(TioSiteTokenPathAccessStatListener.class);

	public static final TioSiteTokenPathAccessStatListener ME_SITE_VIEW = new TioSiteTokenPathAccessStatListener();

	public static final TioSiteTokenPathAccessStatListener ME_SITE_API = new TioSiteTokenPathAccessStatListener();

	private static Set<String> skipExtSet = new HashSet<>();

	static {
		skipExtSet.add("css");
		skipExtSet.add("js");
		skipExtSet.add("ico");
		skipExtSet.add("png");
		skipExtSet.add("jpg");
		skipExtSet.add("swf");
		skipExtSet.add("xml");
		skipExtSet.add("gif");
		skipExtSet.add("jpeg");
		skipExtSet.add("woff");
		skipExtSet.add("map");
		skipExtSet.add("txt");

		skipExtSet.add("mp4");
		skipExtSet.add("m3u8");
		skipExtSet.add("svg");
	}

	@Override
	public void onExpired(TioConfig tioConfig, String token, TokenAccessStat tokenAccessStat) {
		if (Objects.equals(tokenAccessStat.getDurationType(), Const.TokenPathAccessStatDuration.DURATION_2)) {
			if (log.isDebugEnabled()) {
				log.debug("token:{}, \r\ntokenAccessStat:{} ", token, Json.toFormatedJson(tokenAccessStat));
			}
		}
	}

	private static final String CONF_PREFIX = "token.access.";

	private static final int STEP = ConfService.getInt(CONF_PREFIX + "STEP", 200);

	private static final int	G1_MAX_COUNT		= ConfService.getInt(CONF_PREFIX + "G1_MAX_COUNT", 200);
	private static final int	G1_MAX_PER_SECOND	= ConfService.getInt(CONF_PREFIX + "G1_MAX_PER_SECOND", 5);

	private static final int	G2_MAX_COUNT		= ConfService.getInt(CONF_PREFIX + "G2_MAX_COUNT", 100);
	private static final int	G2_MAX_PER_SECOND	= ConfService.getInt(CONF_PREFIX + "G2_MAX_PER_SECOND", 10);

	@Override
	public boolean onChanged(HttpRequest httpRequest, String token, String path, TokenAccessStat tokenAccessStat, TokenPathAccessStat tokenPathAccessStat) {
		int allcount = tokenAccessStat.count.get();

		if (allcount % STEP != 0) {
			return true;
		}

		log.debug("token:{}, path:{}", token, path);
		double preSecond = tokenAccessStat.getPerSecond();

		boolean g1;
		boolean g2;

		boolean g1_c1 = allcount > G1_MAX_COUNT; //总访问次数大于该值
		boolean g1_c2 = preSecond > G1_MAX_PER_SECOND; //平均每秒访问次数大于该值
		g1 = g1_c1 && g1_c2;
		if (g1) {
			return false;
		}

		boolean g2_c1 = allcount > G2_MAX_COUNT; //总访问次数大于该值
		boolean g2_c2 = preSecond > G2_MAX_PER_SECOND; //平均每秒访问次数大于该值
		g2 = g2_c1 && g2_c2;
		if (g2) {
			return false;
		}

		String sessionId = DefaultHttpRequestHandler.getSessionId(httpRequest);
		if (StrUtil.isNotBlank(sessionId)) {
			WebApiHttpSessionListener.isValidSessionId(sessionId);
		}

		return true;
	}
}
