package cn.myapps.runtime.rest.security;

import cn.myapps.common.util.Security;
import cn.myapps.runtime.rest.security.service.AccessTokenService;
import cn.myapps.runtime.rest.security.service.JwtAccessTokenServiceImpl;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * REST接口安全拦截器，用于校验客户端发送的AccessToken参数的合法性
 * 
 * @author Happy
 *
 */
public class RestSecurityHandlerInterceptor extends HandlerInterceptorAdapter {

	private static final Logger log = LoggerFactory.getLogger(RestSecurityHandlerInterceptor.class);

	@Autowired
	@Qualifier("jwtAccessTokenService")
	private AccessTokenService accessTokenService = new JwtAccessTokenServiceImpl();

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		// 对客户端发送的AccessToken参数进行校验，通过返回true，否则返回false
		// 获取accessToken
		String login = request.getContextPath() + "/api/runtime/login.*";
		String dingdingLogin = request.getContextPath() + "/api/runtime/dingding/authlogin";
		String syncDataForm = request.getContextPath() + "/api/runtime/synchronization.*";
		String syncOperation = request.getContextPath() + "/runtime/sync/.*";
		String uri = request.getRequestURI();
		if (uri.matches("^" + login) || uri.matches("^" + dingdingLogin) ||
				uri.matches("^" + syncDataForm) || uri.matches("^" + syncOperation) ||
				uri.indexOf("/showjrxml/") >= 0 || uri.indexOf("/getCustomColumnsInfos") >= 0 || uri.indexOf("/accessToken") >= 0 ||
				(uri.contains("/components/do-refresh") && "put".equalsIgnoreCase(request.getMethod()))
		) {
			return true;
		}
		try {
			if (uri.indexOf("/rest/") > -1) {
				if (accessTokenService.checkAccessToken(request.getParameter("accessToken"), "teemlink_obpm")) {
					return true;
				}
			}
			String userId = Security.getUserIdFromToken(request);
			if (userId == null) {
				userId = Security.getDebugUserIdFromToken(request);
				if (userId == null) {
					return false;
				} else {
					String token = Security.getToken(userId);
					//如果过期时间减去当前时间小于12小时，刷新token
					if (Security.getDebugUserExpiresAtFromToken(request) - System.currentTimeMillis() < Security.REFRESH_TIME) {
						Cookie cookie = new Cookie(Security.DEBUG_TOKEN, token);
						cookie.setPath("/");
						response.addCookie(cookie);
					}
				}
			} else {
				String token = Security.getToken(userId);
				//如果过期时间减去当前时间小于12小时，刷新token
				if (Security.getUserExpiresAtFromToken(request) - System.currentTimeMillis() < Security.REFRESH_TIME) {
					Cookie cookie = new Cookie(Security.ACCESS_TOKEN, token);
					cookie.setPath("/");
					response.addCookie(cookie);
				}
			}

		} catch (Exception e) {
			return false;
		}

		return super.preHandle(request, response, handler);
	}

	/**
	 * response 写入accessToken的错误信息(json格式)
	 * 
	 * @param response
	 * @param msg
	 */
	private void writeErrorJsonMsg(HttpServletResponse response, String msg) throws Exception {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");

		JSONObject jsonObject = new JSONObject();
		jsonObject.put("errcode", 500);
		jsonObject.put("errmsg", msg);

		response.getWriter().write(jsonObject.toString());
	}

}
