package sgc.portal.security;

import sgc.portal.SgcPortalAttributes;
import sgc.portal.base.util.EasyHashMap;
import sgc.portal.base.util.SessionUtil;
import sgc.portal.base.util.StringUtil;
import sgc.portal.security.annotation.SecurityPolicy;
import sgc.portal.com.sym.user.model.UserDetails;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

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

/**
 * <pre>
 * 인증(로그인)되지 않은 사용자가 접근하지 못 하도록
 * 사용자 세션을 감시한다.
 * </pre>
 *
 * @author YongSang
 * @version 1.0.0
 * @since 2020. 7. 28.ResolvedMessageErrorAttributes
 */
public class SessionObserver extends HandlerInterceptorAdapter {
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		SecurityPolicy policy = (SecurityPolicy) request.getAttribute(SgcPortalAttributes.SECURITY_POLICY);
		if (policy == SecurityPolicy.SESSION || policy == SecurityPolicy.PROTECTED) {
			UserDetails userDetails = (UserDetails) SessionUtil.getAttribute(SgcPortalAttributes.AUTHENTICATION);
			if (userDetails == null) {
				return throwException(request, response, handler, userDetails);
			}
			String connIp = StringUtil.getConnIp(request);
			String connBrowser = StringUtil.getConnBrowser(request);
			if (!connIp.equals(userDetails.getConnIp()) || !connBrowser.equals(userDetails.getConnBrowser())) {
				HttpSession session = request.getSession();
				SessionUtil.setAttribute(SgcPortalAttributes.AUTHENTICATION, null);
				session.invalidate();
				return throwException(request, response, handler, userDetails);
			}
		}
		return true;
	}

	public boolean throwException(HttpServletRequest request, HttpServletResponse response, Object handler, UserDetails userDetails) {
		String requestURI = request.getRequestURI();
		try {
			if (requestURI.startsWith("/websquare")) {
				response.sendRedirect("/websquare/?nextUrl=" + requestURI);
			} else if (requestURI.startsWith("/mobile")) {
				ObjectMapper mapper = new ObjectMapper();
				EasyHashMap<String, String> msg = new EasyHashMap<>();
				msg.put("message", "exception.session.invalid");
				msg.put("connBrowser", StringUtil.getConnBrowser(request));
				if (userDetails != null) {
					msg.put("userDetails", userDetails.getConnBrowser());
				}
				response.setContentType("application/json");
				response.setStatus(HttpServletResponse.SC_OK);
				response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
				response.setHeader("Access-Control-Allow-Credentials", "true");
				response.getWriter().write(mapper.writeValueAsString(msg));
				return false;
			} else {
				throw new InvalidSessionException("exception.session.invalid");
			}
		} catch (IOException e) {
			throw new InvalidSessionException("exception.session.invalid");
		}
		return false;
	}
}