
package org.tio.sitexxx.server.http;

import cn.hutool.core.util.StrUtil;
import org.tio.sitexxx.server.auth.AccessCtrlConfig;
import org.tio.sitexxx.server.auth.AccessCtrlService;
import org.tio.sitexxx.server.utils.WebUtils;
import org.tio.http.common.*;
import org.tio.http.server.intf.HttpServerInterceptor;
import org.tio.http.server.util.Resps;
import org.tio.sitexxx.service.model.main.User;
import org.tio.sitexxx.service.vo.AppCode;
import org.tio.sitexxx.service.vo.Devicetype;
import org.tio.sitexxx.service.vo.RequestExt;
import org.tio.sitexxx.service.vo.RequestKey;
import org.tio.utils.resp.Resp;

/**
 * @author tanyaowu
 * 2016年8月3日 下午1:27:05
 */
public class WebApiHttpServerInterceptor implements HttpServerInterceptor {
	public static final WebApiHttpServerInterceptor ME = new WebApiHttpServerInterceptor();

	/**
	 * 安卓APP的每个请求都要传这个参数: p_is_android=1
	 */
	public static final String	PARAM_NAME_IS_FROM_ANDROID	= "p_is_android";
	/**
	 * IOS APP的每个请求都要传这个参数: p_is_ios=1
	 */
	public static final String	PARAM_NAME_IS_FROM_IOS		= "p_is_ios";
	/**
	 * 电脑版client(注：不是web，是用java或者c写的程序) 的每个请求都要传这个参数: p_is_pc=1
	 */
	public static final String	PARAM_NAME_IS_FROM_PC		= "p_is_pc";

	private AccessCtrlConfig accessCtrlConfig;

	@Override
	public HttpResponse doBeforeHandler(HttpRequest request, RequestLine requestLine, HttpResponse httpResponseFromCache) throws Exception {
		RequestExt requestExt = new RequestExt();
		request.setAttribute(RequestKey.REQUEST_EXT, requestExt);
		requestExt.setCanCache(false);
		String path = requestLine.getPath(); //这个是去头和去尾的，形如: /video/videoList
		boolean isFromAndroid = "1".equals(request.getParam(PARAM_NAME_IS_FROM_ANDROID));
		boolean isFromIos = "1".equals(request.getParam(PARAM_NAME_IS_FROM_IOS));
		boolean isFromPc = "1".equals(request.getParam(PARAM_NAME_IS_FROM_PC));
		boolean isFromApp = isFromIos || isFromAndroid || isFromPc;
		if (isFromApp) {
			requestExt.setFromApp(true);
			requestExt.setFromBrowser(false);
			requestExt.setFromBrowserPc(false);
			requestExt.setFromBrowserMobile(false);

			// 安卓和ios只能登录一个
			requestExt.setAppDevice(Devicetype.APP.getValue());
			if (isFromIos) {
				requestExt.setFromAppIos(true);
				requestExt.setDeviceType(Devicetype.IOS.getValue());
			} else if (isFromAndroid) {
				requestExt.setFromAppAndroid(true);
				requestExt.setDeviceType(Devicetype.ANDROID.getValue());
			} else {
				requestExt.setFromPcClient(true);
				requestExt.setDeviceType(Devicetype.PC.getValue());
				requestExt.setAppDevice(Devicetype.PC.getValue());
			}
		}

		//看看access_token end

		//统一检查pageSize
		String pageSize = request.getParam("pageSize");
		if (StrUtil.isNotBlank(pageSize)) {
			String remark = null;
			try {
				int _pageSize = Integer.parseInt(pageSize);
				if (_pageSize > 1000) {
					remark = "pageSize参数值[" + _pageSize + "]过大，被认为是攻击";
				}
			} catch (NumberFormatException e) {
				remark = "pageSize参数值[" + pageSize + "]不是数字，被认为是攻击";
			}

			if (remark != null) {
				request.close(remark);
				return null;
			}
		}

		boolean b = AccessCtrlService.canAccess(accessCtrlConfig, path);
		if (!b) {
			User user = WebUtils.currUser(request);
			//没有权限
			if (user == null) {
				return Resps.json(request, Resp.fail("请重新登录").code(AppCode.ForbidOper.NOTLOGIN));
			}
		}
		requestExt.setCanCache(true);
		return null;
	}

	@Override
	public void doAfterHandler(HttpRequest request, RequestLine requestLine, HttpResponse response, long cost) {
		response.addHeader(HeaderName.Access_Control_Allow_Credentials, HeaderValue.TRUE);
	}

	public void setAccessCtrlConfig(AccessCtrlConfig accessCtrlConfig) {
		this.accessCtrlConfig = accessCtrlConfig;
	}
}
