package com.palmnest.webapp.filter;

import com.alibaba.fastjson.JSONObject;
import com.palmnest.application.AppConstants;
import com.palmnest.application.Constants;
import com.palmnest.application.bean.AppResultDto;
import com.palmnest.application.core.util.AppResultUtil;
import com.palmnest.service.redis.BaseRedisService;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.jstl.core.Config;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;

/**
 * Filter to wrap request with a request including user preferred locale.
 */
public class LocaleFilter extends OncePerRequestFilter {
	/**
	 * This method looks for a "locale" request parameter. If it finds one, it sets it as the preferred locale
	 * and also configures it to work with JSTL.
	 *
	 * @param request  the current request
	 * @param response the current response
	 * @param chain    the chain
	 * @throws IOException      when something goes wrong
	 * @throws ServletException when a communication failure happens
	 */
	public void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
								 FilterChain chain)
			throws IOException, ServletException {

		//response.setHeader("Access-Control-Allow-Origin","*");
		//response.setHeader("Access-Control-Allow-Methods","GET,POST,OPTIONS");

		// 请求相对路径带项目路径  /super_service/admin/list
		String uri    = request.getRequestURI();
		String locale = request.getParameter("locale");

		Locale preferredLocale = null;

		// 对客户端api接口进行过滤验证 排除登录
		FilterConfig config            = getFilterConfig();
		String[]     excludedPageArray = null;
		String       excludedPages     = config.getInitParameter("excludedPages");

		if (StringUtils.isNotEmpty(excludedPages)) {
			excludedPageArray = excludedPages.split(",");
		}

		// 排除 页面 start
		boolean isExcludedPage = false;

		// 判断是否在过滤url之外
		for (String page : excludedPageArray) {

			// 相对路径,不带项目路径  /admin/list
			if (request.getServletPath().equals(page)) {
				isExcludedPage = true;
				break;
			}

			if (request.getServletPath().indexOf("/api/userdata") != -1) {
				isExcludedPage = true;
				break;
			}
		}
		// 排除 页面 end

		// 前端 api start TODO 坑位 写死了 content 为 super_service
		if (uri.indexOf("super_service/api") != -1 && !isExcludedPage) {

			String                token            = request.getHeader("token");
			WebApplicationContext web              = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
			BaseRedisService      baseRedisService = web.getBean(BaseRedisService.class);

			try {
				//验证是否合法
				if (StringUtils.isNotEmpty(token) && JwtUtil.checkToken(token)) {

					//验证是否在有效期内
					if (baseRedisService.get(token) == null) {
						AppResultDto rt = AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
						outputJson(response, JSONObject.toJSONString(rt));
					} else {
						chain.doFilter(request, response);
						LocaleContextHolder.setLocaleContext(null);
					}
				} else {
					AppResultDto rt = AppResultUtil.createErrorDto(AppConstants.RESULTCODE_ILLEGAL, "非法请求");
					outputJson(response, JSONObject.toJSONString(rt));
				}
			} catch (Exception e) {
				logger.error("the request params occur null or empty" + e + e.getMessage());
				e.printStackTrace();
			}

		}
		// 前端 api end
		// 后请 请求 start
		else {
			// i18n 国际化 start
			if (locale != null) {
				int indexOfUnderscore = locale.indexOf('_');
				if (indexOfUnderscore != -1) {
					String language = locale.substring(0, indexOfUnderscore);
					String country  = locale.substring(indexOfUnderscore + 1);
					preferredLocale = new Locale(language, country);
				} else {
					preferredLocale = new Locale(locale);
				}
			}
			// i18n 国际化 end

			// TODO 标记 新旧融合 怎样从外部干涉
			HttpSession session = request.getSession(false);

			if (session != null) {

				if (preferredLocale == null) {
					preferredLocale = (Locale) session.getAttribute(Constants.PREFERRED_LOCALE_KEY);
				} else {
					session.setAttribute(Constants.PREFERRED_LOCALE_KEY, preferredLocale);
					Config.set(session, Config.FMT_LOCALE, preferredLocale);
				}

				if (preferredLocale != null && !(request instanceof LocaleRequestWrapper)) {
					request = new LocaleRequestWrapper(request, preferredLocale);
					LocaleContextHolder.setLocale(preferredLocale);
				}
			}

			chain.doFilter(request, response);
			// Reset thread-bound LocaleContext.
			LocaleContextHolder.setLocaleContext(null);
		}
		// 后请 请求 end

	}

	protected void outputJson(HttpServletResponse response, String json) {
		response.setContentType("application/json;charset=utf-8");
		PrintWriter out;
		try {
			out = response.getWriter();
			out.print(json);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
