package com.its.web.interceptor;

import com.its.web.service.common.CommonService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Arrays;

@Slf4j
@RequiredArgsConstructor
public class ConnectHistory implements HandlerInterceptor {

    private final CommonService service;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        InetAddress ipAddress = InetAddress.getLocalHost();
//        String hostIp = ipAddress.getHostAddress();
        String uri = request.getRequestURI();
        String[] ipAddressArr = new String[]{"127.0.0.1", "localhost", "192.168.20.46"};
        HttpSession session = request.getSession();
        String hostIp = getClientIp(request);
        if (session.getAttribute(hostIp) == null && !uri.contains("/phits") && !uri.contains("error")) {
            log.info("Connect Ip Address : {}, UUID : {}", hostIp, session.getId());
            session.setAttribute(hostIp, session.getId());
            try {
                service.insertConnHs();
            }
            catch (DataAccessException e) {
                log.error("접속 이력 등록에 실패하였습니다.");
            }
        }

        boolean isHostIp = Arrays.asList(ipAddressArr).contains(hostIp);
        String redirectPath = null;
        if (uri.contains("/phits")) {
            if (isHostIp) {
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                boolean isLogin = (authentication != null && !(authentication instanceof AnonymousAuthenticationToken) && authentication.isAuthenticated());

                if (isLogin && uri.equals("/phits")) {
                    redirectPath = "/phits/main";
                }
                if (!isLogin && !uri.equals("/phits")) {
                    redirectPath = "/phits";
                }

            }
            else {
                redirectPath = "/";
            }
        }

        if (redirectPath != null) {
            response.sendRedirect(redirectPath);
        }
        return true;
    }

    public String getClientIp(HttpServletRequest request) {
        if (request == null) {
            return "";
        }

        String ipAddress = request.getHeader("X-FORWARDED-FOR");
        // proxy 환경일 경우
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        // 웹로직 서버일 경우
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        // 기타
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr() ;
        }
        //-Djava.net.preferIPv4Stack=true
        if (ipAddress.equals("0:0:0:0:0:0:0:1"))   //==> ipv6 <== default
        {
            ipAddress = "127.0.0.1";   //==> localhost
        }
        return ipAddress;
    }
}
